一.主要思想(进位制思想与移位思想):

{
"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"
}

1).进位制思想

将0-9-a-Z,62个字符做为一个数制表系统,存入一个数组,既62位数字进制,逢"Z"数制进一位,好比9进一位到10。
4位串码前位不够补0,累加的操作只需要将末位往后移动一位循环移动。

由进位制思想可以推出,假如数制表长度为n,在n个无重复元素集合中,取m个元素做组合(长度为x,组合时可复用单个元素),组成为不同的串码组合,可以有n的m次方(n^m或n^x)种组合,即:

C(n,m)=n^m或=n^x;

若 m=4,则C(n,m)=62^4=14776336;//≈1477万

若 m=5,则C(n,m)=62^5=916132832;//≈9亿

若 m=6,则C(n,m)=62^5=56800235584;//≈568亿

以此类推。

2).移位思想

比如:
已知串码[a][b][c][d]
求下一位串码
将末位[d]往后移一位得到:[e]
故求得下一位串码是[a][b][c][e]

二.实现思路

方式1
输入参数:当前串码
输出:新的串码

方式2
根据10进制数值,换算出指定长度的62进制的数串

三.下面走 java代码实现( CombinationCodeV4衍生版本 )

/*** Copyright (C), 2000-2021, XXX有限公司* FileName: CombinationCodeV4衍生版本* Author: wangyetao* Date: 21-10-23 21:00:00* 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,进位逻辑改用[递归]实现* wangyetao,21-10-23 21:00:00,CombinationCodeV4衍生版本,添加next方法*/
package simple.callback.cryptographyalgorithm;/*** @ClassName: CombinationNumberV3* @Description: java类描述* @Author: wangyetao* @Date: 21-10-23 08:30:24*/
public class CombinationCodeV4 {//数制表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;//数位默认长度public static int countIndex = 0;//10进制数字记数器/*** 根据当前串码获取下一位串码** @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);countIndex++;//拼接单独位值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];//数制进位前,本位归0singleCarryup[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;//补位,前位不够补0if (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);}/*** 此方法无须传入当前串码,方法内根据countIndex生成下一位串码* 仅适用在全局单例环境下,由10进制数字转换出62进制的数字串码** @param digit 数位长度* @return 串码*/public String next(int digit) {defaultDigit = digit;//将10进制数字转换出62进制的数字串码String _10_62code = BinaryConversion._10_to_62(countIndex, defaultDigit);String[] digitalTempArr = _10_62code.split("");String[] digitalArr = new String[defaultDigit];//补位检测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);countIndex++;//拼接单独位值StringBuffer tmpBuff = new StringBuffer();for (String tmp : singleDigital)tmpBuff.append(tmp);return tmpBuff.toString();}/*** 根据10进制的数值生成指定长度的62进制的对应码** @param digit  数位长度* @param _10num 10进制数值* @return*/public String next(int digit, int _10num) {defaultDigit = digit;//将10进制的数值转换出62进制的数字串码String _10_62code = BinaryConversion._10_to_62(_10num, defaultDigit);String[] digitalTempArr = _10_62code.split("");String[] digitalArr = new String[defaultDigit];//补位检测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 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 {CombinationCodeV4 combinationNumber = new CombinationCodeV4();//DEMO_TEST1/*String initCode = "0000";int count = 0;count++;long startTime = System.currentTimeMillis();System.out.println(initCode);while (!initCode.equals("ZZZZ")) {initCode = combinationNumber.generateNextCode(4, initCode);count++;System.out.println(initCode);}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 initCode = "0000";int count = 0;count++;long startTime = System.currentTimeMillis();System.out.println(initCode);while (!initCode.equals("ZZZZZZZZZZ")) {initCode = combinationNumber.generateNextCode(10, initCode);count++;System.out.println(initCode);Thread.sleep(100);}long endTime = System.currentTimeMillis();System.out.println("count=" + count + ",耗时" + (endTime - startTime) + "ms");*///DEMO_TEST4_2String initCode = "0";int count = 0;count++;long startTime = System.currentTimeMillis();System.out.println(initCode);while (!initCode.equals("ZZZZ")) {initCode = (String) combinationNumber.next(4);count++;System.out.println(initCode);Thread.sleep(100);}long endTime = System.currentTimeMillis();System.out.println("count=" + count + ",耗时" + (endTime - startTime) + "ms");//DEMO_TEST4_3/*int counter = 0;long startTime = System.currentTimeMillis();while (counter != 14776335) {System.out.println(combinationNumber.next(4,counter));counter++;Thread.sleep(100);}long endTime = System.currentTimeMillis();System.out.println("count=" + counter + ",耗时" + (endTime - startTime) + "ms");*//*//DEMO_TEST5FileOutputStream fos = new FileOutputStream("/home/wangyetao/Documents/CombinationNumberV2Test_DEMO_TEST5.log");String initCode = "0000";int count = 0;count++;long startTime = System.currentTimeMillis();System.out.println(combinationNumber.generateNextCode(10, initCode));fos.write((initCode + "\n").getBytes());while (!initCode.equals("ZZZZ")) {initCode = combinationNumber.generateNextCode(10, initCode);count++;System.out.println(initCode);fos.write((initCode + "\n").getBytes());}fos.close();long endTime = System.currentTimeMillis();System.out.println("count=" + count + ",耗时" + (endTime - startTime) + "ms");*/}}

进制转换工具类 BinaryConversion.java

/*** Copyright (C), 2000-2021, XXX有限公司* FileName: BinaryConversion* Author: wangyetao* Date: 21-10-23 21:58:38* Description: 进制转换* History:* <author> <time> <version> <desc>* 作者姓名 修改时间 版本号 版本描述*/
package simple.callback.cryptographyalgorithm;import java.util.Stack;/*** @ClassName: BinaryConversion* @Description: 进制转换工具类* @Author: wangyetao* @Date: 21-10-23 21:58:38*/
public class BinaryConversion {private static char[] charSet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();/*** 将10进制转化为62进制** @param number* @param length 转化成的62进制长度,不足length长度的话高位补0,否则不改变什么* @return*/public static String _10_to_62(long number, int length) {Long rest = number;Stack<Character> stack = new Stack<Character>();StringBuilder result = new StringBuilder(0);while (rest != 0) {stack.add(charSet[new Long((rest - (rest / 62) * 62)).intValue()]);rest = rest / 62;}for (; !stack.isEmpty(); ) {result.append(stack.pop());}int result_length = result.length();StringBuilder temp0 = new StringBuilder();for (int i = 0; i < length - result_length; i++) {temp0.append('0');}return temp0.toString() + result.toString();}/*** 将62进制转换成10进制数** @param ident62* @return*/private static String convertBase62ToDecimal(String ident62) {int decimal = 0;int base = 62;int keisu = 0;int cnt = 0;byte ident[] = ident62.getBytes();for (int i = ident.length - 1; i >= 0; i--) {int num = 0;if (ident[i] > 48 && ident[i] <= 57) {num = ident[i] - 48;} else if (ident[i] >= 97 && ident[i] <= 122) {num = ident[i] - 97 + 10;} else if (ident[i] >= 65 && ident[i] <= 90) {num = ident[i] - 65 + 10 + 26;}keisu = (int) java.lang.Math.pow((double) base, (double) cnt);decimal += num * keisu;cnt++;}return String.format("%08d", decimal);}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stub//System.out.println("62System=" + _10_to_62(Integer.parseInt("35174605"), 5));//System.out.println("10System=" + convertBase62ToDecimal("2NaWL"));System.out.println("62System=" + _10_to_62(Integer.parseInt("14776335"), 4));System.out.println("10System=" + convertBase62ToDecimal("ZZZZ"));}}

在此记录与总结,2021年 10月 24日 星期日 10:39:19 CST。

组合学:使用10个数字与52个字母生成1477万个不重复的4位串码V4衍生版本相关推荐

  1. 组合学:使用10个数字与52个字母生成1477万个不重复的4位串码V3完结版本

    一.主要思想(进位制思想): 将0-9-A-z,62个字符做为一个进制系统,存入一个数组,既62位数字进制,4位串码前位不够补0. 累加的操作只需要将末位往后移动一位循环移动,逢"Z&quo ...

  2. 组合学:使用10个数字与52个字母生成1477万个不重复的4位串码

    使用10个数字与52个字母生成1477万个不重复的4位串码(比如应用系统流水号应用场景),那么如何实现动态生成这类串码,并保证其不重复呢? 一.主要思想(进位思想): 将0-9-A-z,62个字符做为 ...

  3. python随机生成30个8_Python生成六万个随机,唯一的8位数字和数字组成的随机字符串实例...

    上代码: 环境:Python3 import random,string s=string.ascii_letters+string.digits print(s) n={''.join(random ...

  4. 组合学:26个字母(含大小写)和10个数字组合为4位串的可能性测算

    使用26个字母(含大小写,实际为52个字母)和10个数字组合一个4位的串码,问有多少种组合? 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k' ...

  5. Excel表Ctrl+v和Ctrl shift+v有什么区别_Ctrl键与10个数字键,26个字母键的组合应用技巧解读...

    键盘是一种必备的输入设备,其应用率最高的就是10个数字和26个字母.如果将这10个数字和26个字母与Ctrl键组合,并应用到Excel中,会是怎样的一种体验. 一.Ctrl与数字键. 1.Ctrl+1 ...

  6. ACMNO.21 C语言-逆序输出 输入10个数字,然后逆序输出。 输入 十个整数 输出 逆序输出,空格分开 样例输入 1 2 3 4 5 6 7 8 9 0

    题目描述 输入10个数字,然后逆序输出. 输入 十个整数 输出 逆序输出,空格分开 样例输入 1 2 3 4 5 6 7 8 9 0 样例输出 0 9 8 7 6 5 4 3 2 1 提示 数组?堆栈 ...

  7. [YTU]_1046 ( 输入10个数字,然后逆序输出)

    Description 输入10个数字,然后逆序输出. Input 十个整数 Output 逆序输出,空格分开 Sample Input 1 2 3 4 5 6 7 8 9 0 Sample Outp ...

  8. Java黑皮书课后题第10章:10.21(被5或6整除)找出能被5或6整除的大于Long.MAX_VALUE的前10个数字

    Java黑皮书课后题第10章:10.21(被5或6整除)找出能被5或6整除的大于Long.MAX_VALUE的前10个数字 题目 代码 结果 题目 都在上面 代码 import java.math.B ...

  9. Java黑皮书课后题第10章:*10.16(被2或3整除)找出所有被2或3整除的有50个十进制位数的前10个数字

    10.16(被2或3整除)找出所有被2或3整除的有50个十进制位数的前10个数字 法一 破题 代码 运行结果 法二 破题 代码 运行结果 法一 破题 本题通过基本数据类型无解(求不出来,不是没有解) ...

最新文章

  1. Wedge 100-32X 100GbE Data Center Switch
  2. .pth is a zip archive (did you mean to use torch.jit.load()?)
  3. 深度丨AI界的七大未解之谜:OpenAI丢出一组AI研究课题
  4. Ubuntu14.04下Neo4j图数据库官网安装部署步骤(图文详解)(博主推荐)
  5. 性能之外:LSI 6Gb/s SAS RAID渠道先行
  6. ITK:对多个线程上的数据进行操作以利用多核处理器
  7. 安卓应用开发顶级框架大盘点,总有一款适合你
  8. wms策略文档_内容策略:技术文档的新理念
  9. Ue4.20 安卓开发配置及Android Studio 调试ue安卓工程
  10. java业务类_Java_业务层开发
  11. nodejs学习笔记-1-文件系统
  12. Oracle 10g 数据库服务器的安装
  13. 深度学习:卷积神经网络从入门到精通
  14. 益智app游戏 android,儿童宝宝益智游戏
  15. ZBrush新手推荐使用这17个小技巧和常用快捷键、笔刷
  16. 读书笔记:司马迁《史记》之孝文本纪
  17. 图片转svg并动态修改其颜色
  18. Power BI中的透视列和逆透视
  19. 基于单片机(STM32F103ZE)的智能家居集成控制器设计
  20. 太棒了,Python和算法简直是绝配

热门文章

  1. 杂谈——如何合并两个有序链表(时间复杂度为O(n))
  2. antd upload取消图片删除按钮
  3. 教你视频批量剪辑制作画中画效果
  4. Java集合--阻塞队列(LinkedBlockingQueue)
  5. 问卷研究的五类分析思路模板
  6. 取消华为mate30 删除图片时手机弹出提示:“..检测xx删除了图片..“
  7. Spring Boot 使用 QQ邮箱发邮件
  8. 视频中地点位置标题文字标记介绍动画AE字幕模板
  9. 关于华为HS8145V 进入华为界面后 再刷回电信界面
  10. lda主题模型python实现篇_主题模型TopicModel:通过gensim实现LDA