适配md5老算法
新平台开发的系统和老系统混合使用遇到个烦人问题。老系统对字符串md5和新系统算的不一样。老系统是很近以前开发的开发商早没影了只好反编译得到算法如下public static String Md5(String input){ MessageDigest md MessageDigest.getInstance(MD5); byte[] digest md.digest(input.getBytes()); BigInteger bi new BigInteger(digest); return bi.toString(16); }这段代码的缺陷new BigInteger(digest)会把 MD5 字节数组转成有符号整数结果可能带负号不会自动补全前导零导致长度不固定不是标准 32 位新系统是前端做md5发往后端验证代码如下import md5 from js-md5;md5(data)这种写法会导致两端计算结果不一样。修正如下function eHRMd5(str) { // 1. 用js-md5拿到标准字节数组 const bytes md5.digest(str); // 2. 转Java风格有符号BigInteger const bi bytesToJavaSignedHex(bytes); // 3. 输出和后端一致的结果 return bi.toString(16); } // 【纯数字实现】无 8n、无 0n、无任何 BigInt 语法 function bytesToJavaSignedHex(bytes) { let hex ; const negative (bytes[0] 0x80) ! 0; if (negative) { // 负数补码计算 let temp []; let carry 1; for (let i bytes.length - 1; i 0; i--) { let val 255 - bytes[i] carry; carry val 255 ? 1 : 0; temp[i] val 255; } hex bytesToHex(temp); hex - hex.replace(/^0/, ); // 去前导零 负号 } else { // 正数 hex bytesToHex(bytes).replace(/^0/, ); } return hex || 0; } // 字节数组转十六进制 function bytesToHex(bytes) { return Array.from(bytes, b (b 0xff).toString(16).padStart(2, 0) ).join(); }