java generates redemption code gift package code

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);
		
	}
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324579214&siteId=291194637