起因

对于随机不反复字符串,如果没有长度限度,那么最简略的办法以后工夫戳 + 固定位数随机字符串的模式齐全能够满足(仍有概率反复,但简直能够疏忽),至于长度,有很多方法解决,但最终也无奈做到很短。

最近公司有个小需要,把邀请码升高到四位,四位不反复邀请码的实现形式就不那么随便了,直观的想法是通过10个数字(0-9) + 26个小写字母(a-z)排列组合实现,即所谓的排列可反复问题。

这类问题公式如下,每次n种抉择,抉择r次的排列共有:n的r次幂。这很好了解,一次有n种抉择,第二次有n∗n种抉择,……,第r次有nr种抉择。

对应咱们的需要,也就是能够有36的4次幂 = 1679616种组合,齐全能够满足一个小型我的项目的需要。如果我的项目比拟大,齐全能够通过退出其余项(比方特殊字符、大写字母等等)到可择列表实现,最终还能够晋升邀请码位数进一步扩大。

思路比拟直观简略,但也比拟实用,欢送大家学习交换。

实现

思路:

1、首先要确定随机数的根据,采纳递增数字(能够对应数据库id)作为根底,创立随机串。
2、打乱10个数字 + 26个字母的组合,这样随机数看起来会难受一些。
3、把基数转换成36进制数字,转换后有余4位则补充0位。
4、把四位数字的每一位作为下标对应打乱后10个数字 + 26个字母的组合的列表。
5、组合成4位惟一随机字符串。

上面是代码:

exports.random = (number) => {  // 打乱的10个数字 + 26个字母  const arr = ["m","0","j","f","8","o","z","w","5","t","p","a","1","d","s","h","v","x","9","b","r","y","2","e","7","4","3","q","6","n","u","l","c","g","i","k"];  // 把number由十进制数转换成36进制数  const transNumber = binaryConversion(+number, 10, 36);  // 排除大于4位的状况  const len = transNumber.toString().length;  if (len > 4) {    console.log('数字过大');    return;  }  // 转换后的数字有余4位则补充0位,并按字符转换成数组  const list = prefixInteger(transNumber, 4).toString().split('');  const len4Arr = [];  for (const num of list) {    // 判断以后字符是数字还是字母    const type = checkStrType(num);    // 如果是数字不解决,如果是字母则转换成对应的数组(10 - 35)    const index = type === 'string' ? stringTonum(num) + 9 : num;    len4Arr.push(arr[+index]);  }  // 返回后果  return len4Arr.join('');}

补充

毛病:基数数字低于36无奈创立,比方起始数字大于36。

欢送大家提出高效思路,不足之处请指出。

其余代码如下:

function binaryConversion(num, m ,n) {  return parseInt(String(num), m).toString(n);}function prefixInteger(num, length) { return (Array(length).join('0') + num).slice(-length);}function stringTonum(a) {  const str = a.toLowerCase().split('');  const al = str.length;  const getCharNumber = charx => charx.charCodeAt() - 96;  let numout = 0;  let charnum = 0;  for (let i = 0; i < al; i++) {      charnum = getCharNumber(str[i]);      numout += charnum * Math.pow(26, al - i - 1);  };  return numout;}function checkStrType(str) {  //验证是否是英文  var pattern = new RegExp("[A-Za-z]+");  if (pattern.test(str)) return 'string';  //验证是否是数字  var patternNumber = new RegExp("[0-9]+");  if (patternNumber.test(str)) return 'number';  return '';}