一.主要思想(进位制思想):
将0-9-A-z,62个字符做为一个进制系统,存入一个数组,既62位数字进制,4位串码前位不够补0。
累加的操作只需要将末位往后移动一位循环移动,逢"Z"数制进一位。好比9进一位到10。
{
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"
, "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
}
比如:
已知串码[a][b][c][d]
求下一位串码
将末位[d]往后移一位得到:[e]
故求得下一位串码是[a][b][c][e]
二.实现思路
输入参数:当前串码
输出:新的串码
三.下面走 java代码实现( CombinationNumberV3 )
/**
* Copyright (C), 2000-2021, XXX有限公司
* FileName: CombinationNumberV3
* Author: wangyetao
* Date: 21-10-23 08:30:24
* Description:使用10个数字与52个字母生成n个不重复的n位串码,相当于62位数进制
* 将0-9-A-z,62个字符做为一个进制系统,存入一个数组,既62位数字进制,4位串码前位不够补0。
* 累加的操作只需要将末位往后移动一位循环移动,逢"Z"数制进一位。好比9进一位到10。
* <p>
* 比如:
* * 已知串码[a][b][c][d]
* * 求下一位串码
* * 将末位[d]往后移一位得到:[e]
* * 故求得下一位串码是[a][b][c][e]
* 主要思路:
* * 补位+进位+递归
* <p>
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 版本描述
* wangyetao,21-10-21 15:29:22,CombinationNumberV2,版本描述
* wangyetao,21-10-23 08:30:24,CombinationNumberV3,进位逻辑改用[递归]实现
*/
package simple.callback.cryptographyalgorithm;
/**
* @ClassName: CombinationNumberV3
* @Description: java类描述
* @Author: wangyetao
* @Date: 21-10-23 08:30:24
*/
public class CombinationNumberV3 {
private static String[] digitalsystemtable = {
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"
, "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
};
private static int DIGITALMETER_LENGTH = digitalsystemtable.length;//数制表长度
private int defaultDigit = 4;//数位默认长度
/**
* 根据当前串码获取下一位串码
*
* @param digit 数位长度
* @param currentCodeStr 当前串码
* @return 获取下一位串码
*/
public String generateNextCode(int digit, String currentCodeStr) {
defaultDigit = digit;
String[] digitalTempArr = currentCodeStr.split("");
String[] digitalArr = new String[defaultDigit];
//串码检测
boolean isCompliance = filterCharacter(currentCodeStr);
if (!isCompliance) {
return "不合规的串码参数";
}
//补位检测
digitalArr = doComplement(digitalTempArr);
//保存单独位值
String[] singleDigital = new String[defaultDigit];
for (int i = 0; i < digitalArr.length; i++)
singleDigital[i] = digitalArr[i];
//进位开关
boolean[] singleCarryup = new boolean[defaultDigit];
int carryupLength = singleCarryup.length;
for (int i = 0; i < carryupLength; i++)
singleCarryup[i] = false;
//进位思想主要逻辑递归代码
singleDigital = recursiveNext(singleDigital, singleCarryup, 1);
//拼接单独位值
StringBuffer tmpBuff = new StringBuffer();
for (String tmp : singleDigital)
tmpBuff.append(tmp);
return tmpBuff.toString();
}
/**
* 数制运算与递归进位运算
*
* @param inSingleDigital 单独位值
* @param inSingleCarryup 进位开关
* @param step 步长为1
*/
private String[] recursiveNext(String[] inSingleDigital, boolean[] inSingleCarryup, int step) {
String[] singleDigital = inSingleDigital;
boolean[] singleCarryup = inSingleCarryup;
//步长控制A处:步长不能超过进位开关数长度;递归出口条件;
//当步长大于进位开关数长度时,说明此时所有的位值均须进位,此时首位已到达最大值,无须再进位,归为0,进入下一轮。
if (step <= singleDigital.length) {
int inBinary62Index = indexOfDigitalsystemtable(singleDigital[defaultDigit - step]);
inBinary62Index++;//下标后移一位
if (inBinary62Index > DIGITALMETER_LENGTH - 1) {//进位检测
singleDigital[defaultDigit - step] = digitalsystemtable[0];//数制进位前,本位归0
singleCarryup[singleCarryup.length - step] = true;//打开开关,数制进一位
if (singleCarryup[singleCarryup.length - step]) {
step++;
recursiveNext(singleDigital, singleCarryup, step);//进位递归
}
} else {
singleDigital[defaultDigit - step] = digitalsystemtable[inBinary62Index];//单独位值取后移一位的值,即"+1"
}
}
return singleDigital;
}
/**
* 补位,前位不够补0
*
* @param inDigitalTempArr
* @return targetArr
*/
private String[] doComplement(String[] inDigitalTempArr) {
String[] inTempArr = inDigitalTempArr;//[1][2][3]
String[] targetArr = new String[defaultDigit];//[][][][]
int differ = targetArr.length - inTempArr.length;
//补位,前位不够补0
if (inTempArr.length < targetArr.length) {
//1)保存已有的值到目标数组
for (int i = 0; i < inTempArr.length; i++)
targetArr[i + differ] = inTempArr[i];
//2)补位
for (int i = 0; i < differ; i++)
targetArr[i] = "0";
} else {
for (int i = 0; i < defaultDigit; i++)
targetArr[i] = inTempArr[i];
}
return targetArr;
}
/**
* 根据当前串码获取下一位串码
*
* @param digit 数位长度
* @param currentCodeStr 当前串码
* @return 获取下一位串码
*/
private String next(int digit, String currentCodeStr) {
return generateNextCode(digit, currentCodeStr);
}
/**
* 检索值在数组中的下标
*
* @param binaryValue
* @return 下标
*/
private int indexOfDigitalsystemtable(String binaryValue) {
int sourceIndex = -1;
for (int i = 0; i < DIGITALMETER_LENGTH; i++) {
if (binaryValue.equals(digitalsystemtable[i])) {
sourceIndex = i;
break;
}
}
return sourceIndex;
}
/**
* 判断是否是合规串码
*
* @param currentCodeStr 串码
* @return
*/
private boolean filterCharacter(String currentCodeStr) {
boolean isCompliance = true;
String[] digitalTempArr = currentCodeStr.split("");
for (int i = 0; i < digitalTempArr.length; i++) {
if (indexOfDigitalsystemtable(digitalTempArr[i]) < 0) {
isCompliance = false;
break;
}
}
return isCompliance;
}
/**
* 测试用例
*
* @param args
*/
public static void main(String[] args) throws InterruptedException {
CombinationNumberV3 combinationNumber = new CombinationNumberV3();
//DEMO_TEST1
/*String initStr = "0000";
int count = 0;
count++;
long startTime = System.currentTimeMillis();
System.out.println(initStr);
while (!initStr.equals("ZZZZ")) {
initStr = combinationNumber.generateNextCode(4, initStr);
count++;
System.out.println(initStr);
}
long endTime = System.currentTimeMillis();
System.out.println("count=" + count + ",耗时" + (endTime - startTime) + "ms");*/
//DEMO_TEST2
/*System.out.println(combinationNumber.generateNextCode(5, "0000"));
System.out.println(combinationNumber.generateNextCode(5, "ahzz"));
System.out.println(combinationNumber.generateNextCode(5, "YYYY"));
System.out.println(combinationNumber.generateNextCode(5, "ZZYZ"));
System.out.println(combinationNumber.generateNextCode(5, "ZZZY"));
System.out.println(combinationNumber.generateNextCode(5, "ZZZZ"));
System.out.println(combinationNumber.generateNextCode(5, "ZZZZZZZZZZ"));*/
//DEMO_TEST3
/*System.out.println(combinationNumber.generateNextCode(10, "000"));
System.out.println(combinationNumber.generateNextCode(10, "00"));
System.out.println(combinationNumber.generateNextCode(10, "0"));
System.out.println(combinationNumber.generateNextCode(10, ""));
System.out.println(combinationNumber.generateNextCode(10, "000-"));
System.out.println(combinationNumber.generateNextCode(10, "-00-"));
System.out.println(combinationNumber.generateNextCode(10, "0-0-"));
System.out.println(combinationNumber.generateNextCode(10, "--0-"));
System.out.println(combinationNumber.generateNextCode(10, "----"));
System.out.println(combinationNumber.generateNextCode(10, "ZZHZAA"));*/
//DEMO_TEST4
String initStr = "0000";
int count = 0;
count++;
long startTime = System.currentTimeMillis();
System.out.println(initStr);
while (!initStr.equals("ZZZZZZZZZZ")) {
initStr = combinationNumber.generateNextCode(10, initStr);
count++;
System.out.println(initStr);
Thread.sleep(100);
}
long endTime = System.currentTimeMillis();
System.out.println("count=" + count + ",耗时" + (endTime - startTime) + "ms");
/*//DEMO_TEST5
FileOutputStream fos = new FileOutputStream("/home/wangyetao/Documents/CombinationNumberV2Test_DEMO_TEST5.log");
String initStr = "0000";
int count = 0;
count++;
long startTime = System.currentTimeMillis();
System.out.println(combinationNumber.generateNextCode(10, initStr));
fos.write((initStr + "\n").getBytes());
while (!initStr.equals("ZZZZ")) {
initStr = combinationNumber.generateNextCode(10, initStr);
count++;
System.out.println(initStr);
fos.write((initStr + "\n").getBytes());
}
fos.close();
long endTime = System.currentTimeMillis();
System.out.println("count=" + count + ",耗时" + (endTime - startTime) + "ms");*/
}
}
CombinationNUmberV3_TEST4与输出(CombinationNUmberV3_TEST4run.gif):
CombinationNUmberV3_TEST4_2run.gif:
在此记录与总结,2021年 10月 23日 星期六 11:08:59 CST。