Java 生成任意位数永不重复的随机数策略实现
来源:互联网 发布:sql 外键必须是主键吗 编辑:程序博客网 时间:2024/05/29 19:23
原文:http://blog.csdn.net/shzy1988/article/details/54970421?locationNum=1&fps=1
在项目中遇到客户一个需求,ID的生成策略:长度8位,用户在知道自己的ID(如:10000018)后,不能通过ID来推测相关信息,如用户可能推测我是第18个注册用户,上一个注册用户的ID是10000017,这样就不能很好的保护账号安全了,可以凭证推测数据来进行不法之事。
经过网上查找和思考,便有了如下的解决方案:
- 生成一个装有1-99999999数值的数组
- 将数值内的值随机打乱
- 将数值的值分开保存到不同的文件(txt)中
- 获取ID的时候,可以随机从任意一文件中获取第一行的ID值,然后将剩余行的ID值重写写会原文件
- 如果文件中的ID值已经取完则删除
逻辑很简单,就看实现了,代码如下:
生成ID并保存到硬盘
/** * 生成1-99999999的数字编码保存到硬盘 */ private static void generateAppCode2Disk(){ int begin = 1; int end = 99999999; int count = begin + end; //生成1到99999999的所有整数 int[] codes = new int[count + 1]; for (int i = begin; i <= end; i++){ codes[i] = i; } //随机交换数据 int index = 0; int tempCode = 0; Random random = new Random(); for (int i = begin; i <= end; i++){ index = random.nextInt(count+1); tempCode = codes[index]; codes[index] = codes[i]; codes[i] = tempCode; } //生成1000个文件,每个文件包含100000个appCode StringBuilder sb = new StringBuilder(); int flag = 100000; System.out.println("***********开始**********"); try { for(int i = begin; i <= end; i++){ sb.append(codes[i]).append("\n"); if(i == end || i%flag == 0){ File folder = new File("D:/IDGenerate"); if(!folder.isDirectory()){ folder.mkdir(); } if(i==end){ i = end +1; } File file = new File("D:/IDGenerate/ID_"+(i/flag)+".txt"); if (!file.exists()) { file.createNewFile(); } BufferedWriter bw=new BufferedWriter(new FileWriter(file.getAbsoluteFile())); bw.write(sb.toString()); bw.flush(); bw.close(); sb = new StringBuilder(); System.out.println("当前i值:"+i+"第"+(i/flag)+"个文件生成成功!"); } } System.out.println("***********结束**********"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
获取ID
//获取唯一8位ID public String createAppCode(){ BufferedWriter bw = null; BufferedReader br = null; FileReader fr = null; FileWriter fw = null; try { String dir = "D:/"; if(StringUtils.isBlank(dir)){ throw new Exception("获取文件路径为空"); } File rootFile = new File(dir); String[] fileNames = rootFile.list(); if(fileNames == null || fileNames.length == 0){ throw new Exception("路径不正确,或者ID已经分配完毕,请联系管理员"); } //获取第一个文件 fr=new FileReader(dir+"/"+fileNames[0]);//获取文件流 br = new BufferedReader(fr); //将流整体读取。 StringBuilder sb = new StringBuilder(); String appCode = ""; String temp; int count =1; while(!StringUtils.isBlank(temp=br.readLine())){ if(count == 1){ count++; appCode = temp; continue; } else{ sb.append(temp).append("\n"); } } br.close(); fr.close(); if(!StringUtils.isBlank(appCode)){ //判断文件内容是否还有下一行 if(sb.length()<=0){ File delFile = new File(dir+"/"+fileNames[0]); if(delFile.exists()){ delFile.delete();//删掉 } } else{ //将剩余内容重写写回文件 fw = new FileWriter(dir+"/"+fileNames[0]); bw=new BufferedWriter(fw); bw.write(sb.toString()); bw.flush(); bw.close(); fw.close(); } String prex = "00000000"; appCode = prex.substring(0,prex.length()-appCode.length())+appCode; return appCode; } else{ throw new Exception("文件中内容为空"); } } catch (Exception e) { log.error("获取ID error:"+e.getMessage()); return null; } finally{ try { if(bw != null)bw.close(); if(br != null)br.close(); if(fr != null)fr.close(); if(fw != null)fw.close(); } catch (IOException e) { log.error("关闭文件流文件异常:"+e.getMessage()); } } }
这样将生成的ID分成1000个文件保存到硬盘,取数据的时候从任意文件中取都可,这样能很好的保证了随机,不重复,而且在测试的时候发现效率还不错,内存,CPU的使用都微乎其微。
为了更好的优化获取ID效率,可以有如下改进:
- 将ID保存到更多的文件中,这样文件的容量就可以很小,加载的时候就更快
预读ID,可以提前预读50,100等数量的ID保存到list中,直接从内存取数据就更快了,不过这逻辑就复杂了很多,要保证list的数据和硬盘数据的同步,就需要更多的代码来判断了
此文章供大家参考,大家有什么好的建议,算法都可以提出来交流的!
2 0
- Java 生成任意位数永不重复的随机数策略实现
- Java 生成任意位数永不重复的随机数策略实现
- java生成任意位数的随机数(转)
- 生成任意位数的随机数
- 生成任意位数的随机数
- Java生成指定位数不重复随机数
- JAVA生成指定位数不重复的随机数,随机数含0-9、A-Z
- JAVA生成指定位数不重复的随机数,随机数含0-9、A-Z
- java随机生成6/8/12位数,要求每次产生的随机数与已生成的随机数不重复
- java生成一定位数的随机数
- java实现生成不重复的随机数,可循环利用
- Java实现生成n个不重复的随机数
- java 生成一个永不重复的数字序列
- 生成指定位数的随机数
- 生成指定位数的随机数
- 生成固定位数的随机数
- 生成指定位数的随机数
- java生成不重复的随机数
- Guava学习笔记【10】:Guava新集合-Table等
- 本CSDN博主将与北京航天航空大学出版社合作出版<嵌入式C语言技术实战开发>一书
- 吝啬的国度(dfs)
- MCM(平均曲率演化)
- Java如何获取xml文件中子节点的属性
- Java 生成任意位数永不重复的随机数策略实现
- 顺序队列
- Android学习日志——第1天
- 如何查看Android帮助文档
- C++ Primer 第5版--练习10.37
- 互联网时代架构师的职责与思考
- Guava学习笔记【11】:Guava cache
- Guava学习笔记【12】:EventBus
- web.绑定事件