import java.util.HashSet; import java.util.Random; import java.util.Set; public class GenSerial { private static final String Base32Alphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; /** * Generate new serial number <br> * <p>Generation rule: 45-bit number (binary)<br> * identification bit + data bit + parity bit<br> * Then map the 55-bit number to the serial number represented by ABCDEFGHJKLMNPQRSTUVWXYZ23456789. To map to 32 characters, every 5 bits represents a character (2^5=32), * All generated serial numbers are 45/5=9 digits. * * @param codeLen code length * @param flag identifier * @param flagBitLen identifier length * @param checkBitLen check digit length * @return */ public static String generateNewCode(int codeLen, int flag, int flagBitLen, int checkBitLen) { Long ret = 0L; // long ID Random random = new Random(); int checkModData = 1<<checkBitLen; int totalBitLen = codeLen*5; int dataBitLen = totalBitLen - checkBitLen - flagBitLen; long randData = (long)(1 + (1L<<dataBitLen - 1) * random.nextDouble()); if(flagBitLen > 0){ flag = flag & ((1<<flagBitLen) - 1); //Prevent offside, if the 16-bit flag is 0xffff ret += (long)flag << (totalBitLen - flagBitLen); //High flag bit } ret + = randData << checkBitLen; // Medium number deferred long checkNum = (ret >> checkBitLen) % checkModData; //Lower parity bit ret += checkNum; // 1 - 7 check digits return convertToBase32SerialCode(ret, codeLen); } public static String generateNewCode(int flag, int flagBitLen) { return generateNewCode(9, flag, flagBitLen, 7); //Generate code 9 digits, activity id 16 digits } public static String generateNewCode(int flag) { int flagBitLen = 0; if(flag == 0){ flagBitLen = 0; }else{ flagBitLen = Integer.toBinaryString(flag).length(); } return generateNewCode(9, flag, flagBitLen, 7); //Generate code 9 bits } public static String generateNewCode() { return generateNewCode(9, 0, 0, 7); //Generate code 9 digits } /** * * @param historyCodeSet historically generated serial number set * @param number * @param codeLen * @param flag * @param flagBitLen * @param checkBitLen * @return */ public static Set<String> generateCodes(Set<String> historyCodeSet, int number, int codeLen, int flag, int flagBitLen, int checkBitLen){ Set<String> generatedCodes = new HashSet<String>(number*4/3+1); if(historyCodeSet == null){ historyCodeSet = new HashSet<String>(0); } while(generatedCodes.size()<number){ String code = generateNewCode(codeLen, flag, flagBitLen, checkBitLen); if(!historyCodeSet.contains(code)){ generatedCodes.add(code); } } return generatedCodes; } /** * * @param historyCodeSet * @param number * @return */ public static Set<String> generateCodes(Set<String> historyCodeSet, int number, int codeLen){ return generateCodes(historyCodeSet, number, codeLen, 0, 0, 7); } /** * * @param historyCodeSet * @param number * @return */ public static Set<String> generateCodes(Set<String> historyCodeSet, int number){ return generateCodes(historyCodeSet, number, 9, 0, 0, 7); } /** * Convert random numbers to BASE32 encoded serial codes * * @return */ private static String convertToBase32SerialCode(long longRandValue, int codeLen) { StringBuffer codeSerial = new StringBuffer(16); long tmpRandValue = longRandValue; for (int i = 0; i < codeLen; i++) { int code = (int) (tmpRandValue & 0x1F); char convertCode = Base32Alphabet.charAt(code); codeSerial.append(convertCode); tmpRandValue = tmpRandValue >> 5; } return codeSerial.reverse().toString(); } /** * Convert redemption code sequence characters into numbers. * * @return */ private static int convertBase32CharToNum(char ch) { int index = Base32Alphabet.indexOf(ch); return index; } /** * Convert serial number to long integer * * @return */ public static long convertBase32CharToNum(String serialCode) { long id = 0; for (int i = 0; i < serialCode.length(); i++) { int originNum = convertBase32CharToNum(serialCode.charAt(i)); if(originNum == -1){ return 0; } id = id << 5; id += originNum; } return id; } /** * Check if the serial number is legal * * @param code * @return */ public static boolean checkCodeValid(String code, int checkBitLen) { long id = 0; int checkModData = 1<<checkBitLen; for (int i = 0; i < code.length(); ++i) { long originNum = convertBase32CharToNum(code.charAt(i)); if (originNum >= 32) return false; // illegal character id = id<<5; id += originNum; } long data = id >> checkBitLen; long checkNum = id & (checkModData-1); // the last 7 digits are the check code if (data% checkModData == checkNum) return true; return false; } public static boolean checkCodeValid(String code) { if(code == null || code.length() == 0){ return false; } return checkCodeValid(code, 7); } /** * Extract the ID from the serial number * * @param code serial number * @param flagBitLen flag bit length * @return */ public static Long getFlagFromCode(String code, int flagBitLen){ long id = convertBase32CharToNum(code); return id >> (code.length()*5-flagBitLen); } public static void main(String[] args) { System.out.println(checkCodeValid("ARXX2BWTE")); long sTime = System.currentTimeMillis(); long eTime = 0L; Set<String> codes = generateCodes(null, 7000000, 9, 0, 0, 7); eTime = System.currentTimeMillis(); System.out.println("耗时 " + (eTime-sTime)/1000 + "秒"); sTime = eTime; Set<String> codes2 = generateCodes(codes, 2000000, 9, 0, 0, 7); codes2.size(); eTime = System.currentTimeMillis(); System.out.println("耗时 " + (eTime-sTime)/1000 + "秒"); String code = generateNewCode(1,10); System.out.println("Serial number: "+code); boolean checkRs = checkCodeValid(code); System.out.println("Serial number" + code + "Is it legal: " + checkRs); long acId = getFlagFromCode(code,10); System.out.println("Identifier: " + acId); long numCode = convertBase32CharToNum(code); System.out.println("Number serial number" + numCode); } }
java generates redemption code gift package code
Guess you like
Origin http://43.154.161.224:23101/article/api/json?id=324579214&siteId=291194637
Recommended
Ranking