CodePwdImpl.java 4.66 KB
package com.yanzuoguang.code;

import com.yanzuoguang.dao.DaoConst;
import com.yanzuoguang.util.helper.ByteHelper;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 加密算法0版实现
 *
 * @author 颜佐光
 */
public class CodePwdImpl implements CodePwd {

    /**
     * 当前算法的名称
     *
     * @return
     */
    @Override
    public String getName() {
        /**
         * 颜佐光的第一个版本的算法
         */
        return "Yanzuoguang.Zero";
    }

    /**
     * 生成二维码
     *
     * @param rand  随机数
     * @param day   日期
     * @param index 序号
     * @param pwd   密码
     * @return 生成的结果
     */
    @Override
    public String getCode(String rand, String day, String index, String pwd) {
        StringBuilder ret = new StringBuilder();

        // 1. 将随即数和天数进行组合生成字符串
        StringBuilder sb = new StringBuilder();
        {
            int randSize = rand.length();
            int daySize = day.length();
            int maxLen = Math.max(rand.length(), day.length());
            for (int i = 0; i < maxLen; i++) {
                if (i < daySize) {
                    sb.append(day.charAt(i));
                }
                if (i < randSize) {
                    sb.append(rand.charAt(i));
                }
            }
        }

        // 2. 将组合后的数字进行交换
        String randDay = sb.toString();
        int randDaySize = randDay.length();
        char[] dayChars = new char[randDaySize];
        {
            for (int i = 0; i < randDaySize; i++) {
                dayChars[i] = randDay.charAt(i);
            }
            for (int i = 0; i < randDaySize / ByteHelper.BYTE_STRING_SIZE; i++) {
                if (i % ByteHelper.BYTE_STRING_SIZE == 0) {
                    int to = randDaySize - i - 1;
                    dayChars[to] = randDay.charAt(i);
                    dayChars[i] = randDay.charAt(to);
                }
            }
            for (int i = 0; i < randDaySize; i++) {
                ret.append(dayChars[i]);
            }
        }

        // 3.a 将随机数和后面的序号组成新的字符串
        String codePwd = index;

        // 3.b 将新的字符串加上密码进行处理
        int newSize = codePwd.length();
        int pwdSize = pwd.length();
        int[] newValue = new int[newSize];

        // 3.c 转换为具体的数字,并且加上密码
        for (int i = 0; i < newSize; i++) {
            int from = Integer.parseInt("" + codePwd.charAt(i));
            int pwdIndex = i % pwdSize;
            int to = Integer.parseInt("" + pwd.charAt(pwdIndex));
            int val = (from + to);
            newValue[i] = val;
        }
        // 根据最后一位数字进行相加
        int last = newValue[newSize - 1];
        for (int i = 0; i < newSize - 1; i++) {
            int flag = 1;
            if (last % 2 == 0) {
                flag = -flag;
            }
            if (newValue[i] % 2 == 0) {
                flag = -flag;
            }
            if (i % 2 == 0) {
                flag = -flag;
            }
            newValue[i] += flag * last;
        }

        // 往后移动5位
        int movePos = newSize / 2;
        int[] toVals = new int[newSize];
        for (int i = 0; i < newSize; i++) {
            int j = i - movePos;
            if (j < 0) {
                j = newSize + j;
            }
            toVals[i] = newValue[j];
        }
        newValue = toVals;

        for (int i = 0; i < newSize; i++) {
            newValue[i] = (newValue[i] % 10 + 10) % 10;
            ret.append(newValue[i]);
        }

        return ret.toString();
    }

    public static void test(String[] args) {
        int[] pos2 = {3, 4, 5, 6, 8};
        int startPos = 0;
        int endPos = 1000000;

        Date start = new Date();
        CodePwdImpl item = new CodePwdImpl();
        Map<String, Integer> map = new HashMap<>(DaoConst.COLLECTION_INIT_SIZE);
        for (int i = startPos; i < endPos; i++) {
            String index = String.format("%09d", i);
            String code = item.getCode("", "", index, "18532354168");
            if (map.containsKey(code)) {
                map.put(code, map.get(code) + 1);
                System.err.println("code: " + map.get(code));
            } else {
                map.put(code, 1);
            }
            int rand2 = pos2[new Random().nextInt(pos2.length)];
            String mobile = "1" + rand2 + code;
            System.out.println(mobile);
        }
        Date end = new Date();
        System.out.println("长度: " + (endPos - startPos) + " time:" + (end.getTime() - start.getTime()));
    }
}