Node.js通过密钥计算验证码,无需存数据库

Node.js通过密钥计算验证码,无需存数据库

const CRC32 = require('crc-32');
function XixiOtp(sKey, iKeeptime = 600) {
    const oPri = {};
    oPri.sKey = sKey;
    oPri.iKeeptime = iKeeptime * 1000;
    oPri.p1Len = 1; // 验证码前缀长度(建议1~2)
    oPri.p2Len = 5; // 验证码后缀长度(建议3~7)
    oPri.sAccount = '';
    oPri.time = () => {
        return +new Date();
    };
    oPri.intval = (num) => {
        return parseInt(num, 10);
    };
    oPri.numPad = (num, len) => {
        // 补零
        const diff = len - num.toString().length;
        const pre = (diff > 0) ? Array(diff + 1).join('0') : '';
        return pre + num;
    };
    oPri.getCrc32 = (str) => {
        var i = CRC32.str(str);
        if (i < 0) {
            i += Math.pow(2, 32);
        }
        return i;
    };
    oPri.getP2 = (iT1, iP1) => {
        // 通过时间和验证码前缀来计算验证码的后缀
        const iT2 = oPri.intval((iT1 - iP1 * oPri.iKeeptime / Math.pow(10, oPri.p1Len)) / oPri.iKeeptime);
        const sP1 = oPri.numPad(iP1, oPri.p1Len);
        const arr = [oPri.sAccount, iT2, sP1, oPri.sKey];
        const crc = oPri.getCrc32(arr.join(','));
        const iP2 = crc % Math.pow(10, oPri.p2Len);
        return oPri.numPad(iP2, oPri.p2Len);
    };
    const oPub = {};
    oPub.setAccount = (sAccount) => {
        oPri.sAccount = sAccount;
    };
    oPub.getCode = () => {
        // 取得Otp验证码
        const iT1 = oPri.time();
        const m = iT1 % oPri.iKeeptime;
        const iP1 = oPri.intval(m * Math.pow(10, oPri.p1Len) / oPri.iKeeptime);
        const iP2 = oPri.getP2(iT1, iP1);
        return oPri.numPad(iP1, oPri.p1Len) + iP2;
    };
    oPub.verify = (sCode) => {
        // 校验Otp验证码是否有效
        const iT1 = oPri.time();
        const sP1 = sCode.substr(0, oPri.p1Len);
        const sP2 = sCode.substr(oPri.p1Len);
        return sP2 === oPri.getP2(iT1, oPri.intval(sP1));
    }
    return oPub;
}
const iKeeptime = 600;
const otp = XixiOtp('feieryun.cn', iKeeptime);
otp.setAccount('309385018@qq.com');
const sCode = otp.getCode();
console.log(sCode);
var i = 0;
setInterval(() => {
    console.log(i, otp.verify(sCode));
    i++;
}, 1000);

Node.js通过密钥计算验证码,无需存数据库

posted on 2022-11-19 20:03  项希盛  阅读(123)  评论(0)    收藏  举报