想实现一个由时间戳+随机字符串组合方式生成重复概率很低的随机字符串,但是纯数字的时间戳是在太显眼,不想让人猜到里面包含了时间戳信息,怎么办,那就对0-9的数字进行编码吧。
最初想到的是使用base64来编码,但是有个问题,时间戳的前三位基本不变动,导致base64编码后的的时间戳还是具有一定的规律性,这不是我想要的。
思虑再三,决定自己来实现一个数字编码算法,将0-9进行随机编码,每个数字都对应着6种可能的字符来替代,比如0 ,可以由 y\p\z\3\O\G 来表示,至于选择这六个字符种的哪一种,则随机决定
首先定义编码字典,用数组来保存:
private val EncodeDict = Seq(
'y', 'i', 'o', 'q', 'w', 'e', 'r', 't', 'y', 'u',
'p', 'a', 's', 'd', 'f', 'g', 'C', 'T', 'F', 'X',
'z', 'x', 'c', 'v', 'b', 'n', 'm', '0', '1', '2',
'3', 'U', "H", 'V', 'Y', '8', '9', 'P', 'L', 'M',
'O', 'K', 'N', 'I', 'J', 'B', '4', '5', '6', '7',
'G', 'h', 'j', 'k', 'l', 'R', 'D', 'Z', 'E', 'S')
共有60个字符,分成6行10列, 每一列表示一个数字,0 由 y\p\z\3\O\G 来表示,1由 i\a\x\U\K\h 来表示, 以此类推。
下面是具体的编码替换方法:
def intEncode(time: Long): String = {
val arr = time.toString.toCharArray
// 首先生成一个0-5之间的随机值
val rand = new Random()
var b = rand.nextInt(6)
val builder = new StringBuilder()
for ( i <- Range(0, arr.length() - 1)) {
// arr(i) 获取的时char的 acsii 码 减去48得到真实值
val v = arr(i) - 48
// 计算在替换字符在字典的位置
val loc = v + b * 10
builder.append(EncodeDict(loc).toString)
// 计算下一个数字的随机值,并保证在0-5之间
b = (b + v) & 0x05
}
builder.toString()
}
Comments | NOTHING