如何按照ascii码顺序生成5位字符串?

济南大飞哥 2016-09-02 10:42:11
需求是需要一个6位数字符串生成算法,也可以随机,也可以不随机(可能不随机更容易实现些),每一位是0~9,a~-z, A~Z, 的一个(共61个字符)。
本来是想用每一位都随机的算法生成的,理论上重复是很低的,但有一个问题是,生成的数都记到数据库了,相当于已经用了,那么随着时间的推移,后来的数与前面的数重复的几率就会增大,一个极端情况是所有的数都出现过后,以后生成的每一个数都是重复的,所以罢了。

a-z:97-122
A-Z:65-90
0-9:48-57

因为最终我们可能只需要使用一部分(最多几千几万),我算了下,一秒钟出现一个,均不重复的话也需要1000多年才能用完,所以需要一个理论上不产生重复的算法。

我是想着参考数字,按照位数进阶的形式生成, 比如最小的数 为 000000 最大数为 zzzzzz, ,想着可以写个序列。
...全文
404 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
NewMoons 2016-09-14
  • 打赏
  • 举报
回复
public class Tools {
	//计数最大长度,默认为0,表示无限大。
	public static int maxLength = 0;
	
	/**
	 * 以 0-9 A-Z a-z 范围的字符计数器函数。计数顺序是以上述字符的ascii码的大小来排序。
	 * 考虑到可能运行在多线程环境,加了同步锁。
	 * @param param 计数参数
	 * @return param加1后的数值
	 * @throws Exception
	 */
	public static synchronized String getNextValue(String param) throws Exception{
		//空值校验
		if(param == null || param.length() == 0){
			return "0";
		}
		//长度校验
		if(param.length() == 0 || param.length() > 6){
			throw new Exception("参数不合法,长度要大于0且小于等于6位!");
		}
		//非法字符校验
		char[] paramChars = param.toCharArray();
		for(int i=0;i<paramChars.length;i++){
			char chr = paramChars[i];
			boolean flag = (chr >= 48 && chr <= 57) || (chr >= 65 && chr <= 90) || (chr >= 97 && chr <= 122);
			if(!flag){
				throw new Exception("参数不合法,含有非 0-9 A-Z a-z 的字符!");
			}
		}
		//计数上限校验,不能超过最大长度位数。
		if(maxLength > 0){
			StringBuilder sb = new StringBuilder();
			for(int i=0;i<maxLength;i++){
				sb.append('z');
			}
			if(sb.toString().equals(param)){
				throw new Exception("参数不合法,已达上限'" + sb.toString() + "'!");
			}
		}
		
		boolean carry = false;
		for(int i = paramChars.length-1;i>=0;i--){
			char chr = paramChars[i];
			//逢'z'进位
			if(chr == 'z'){
				paramChars[i] = '0';
				if(i == 0){
					carry = true;
				}
			}else{
				if(chr == '9'){
					chr = 'A';
				}else if(chr == 'Z'){
					chr = 'a';
				}else{
					chr++;
				}
				paramChars[i] = chr;
				carry = false;
				break;
			}
		}
		param = new String(paramChars);
		if(carry){
			param = "1" + param;
		}
		
		return param;
	}

	public static void main(String[] args) {
		Tools.maxLength = 6;
		String value = "";//表示从0开始计数。
		long count = 0;
		try {
			while(true){
				value = Tools.getNextValue(value);
				count++;
				System.out.println(value);
				//控制输出的最大数值。
				if("zzz".equals(value)){
					break;
				}
			}
			System.out.println("计数次数:" + count);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
济南大飞哥 2016-09-13
  • 打赏
  • 举报
回复
引用 3 楼 NewMoons 的回复:
[quote=引用 2 楼 zhxilo 的回复:] 时间戳加随机数怎么样?
楼主你的表达很有问题啊,说的混乱且不清楚。 你的需求可不可以用这样几点来表达: 1、需要生成一个6位长度的字符串作为唯一索引作为数据库表的主键,即所有生成的字符串不能重复; 2、这个字符串的每个字符范围在:0~9,a~-z, A~Z; 如果是,个人觉得【按照位数进阶的形式生成, 比如最小的数 为 000000 最大数为 zzzzzz,】是最佳方案。 随机生成不仅效率低,而且有重复的可能。 如果是,我再给你提供算法代码。[/quote] 是的,你晒下代码吧。
NewMoons 2016-09-02
  • 打赏
  • 举报
回复
引用 2 楼 zhxilo 的回复:
时间戳加随机数怎么样?
楼主你的表达很有问题啊,说的混乱且不清楚。 你的需求可不可以用这样几点来表达: 1、需要生成一个6位长度的字符串作为唯一索引作为数据库表的主键,即所有生成的字符串不能重复; 2、这个字符串的每个字符范围在:0~9,a~-z, A~Z; 如果是,个人觉得【按照位数进阶的形式生成, 比如最小的数 为 000000 最大数为 zzzzzz,】是最佳方案。 随机生成不仅效率低,而且有重复的可能。 如果是,我再给你提供算法代码。
zhxilo 2016-09-02
  • 打赏
  • 举报
回复
时间戳加随机数怎么样?
Qrcode2 2016-09-02
  • 打赏
  • 举报
回复
UUID怎么样

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧