Contents

一种基于时间戳的随机字符串生成方式

Contents

想实现一个由时间戳+随机字符串组合方式生成重复概率很低的随机字符串,但是纯数字的时间戳是在太显眼,不想让人猜到里面包含了时间戳信息,怎么办,那就对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()
  }