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

这段代码的缺陷:

  1. new BigInteger(digest) 会把 MD5 字节数组转成有符号整数 ,结果可能带负号
  2. 不会自动补全前导零,导致长度不固定(不是标准 32 位)

新系统是前端做md5发往后端验证,代码如下:

import md5 from 'js-md5';

md5(data)

这种写法会导致两端计算结果不一样。修正如下:

javascript 复制代码
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('');
}
相关推荐
shirsl1 小时前
算法 Day 2 滑动窗口 + 栈 / 单调栈
开发语言·python·算法
土司大王2 小时前
LeetCode hot100 回溯专题总结:Java 通用模板、决策树模型
java·算法·leetcode·决策树
2601_962218612 小时前
万象生鲜系统订单全生命周期状态同步技术实现业务可视
大数据·数据库·人工智能·python·算法
那年窗外下的雪.2 小时前
AIDC 学习日志|第 22 天|All-Active/Single-Active 故障演练设计
服务器·网络·学习·算法·哈希算法
wzdark3 小时前
基于启发式搜索的最优路径规划算法研究4
算法
l1t3 小时前
用superpi、tinypi、tpi等工具计算圆周率的比较
c语言·算法
a187927218314 小时前
【算法】链表(二):链表上的双指针——变速、异链与定距,和一份路程账本
数据结构·算法·leetcode·链表·go·指针·环形链表
2601_958352905 小时前
还要写 AEC 算法?0 代码 + 6 个引脚,F-18 让通话清晰度提升 300%
人工智能·算法·降噪消回音
happyprince5 小时前
03-regmix-深刻观-哲学与升华
算法
一路向阳~负责的男人5 小时前
运动控制算法收录
算法