适配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('');
}
相关推荐
小O的算法实验室28 分钟前
IEEE TASE,基于MPC的多无人机协同搜索竞争群体优化方法
算法
Tbisnic1 小时前
BGE-M3 算法详解:从模型架构到三种检索方式的数学原理
算法·自然语言处理·大模型·bert·transformer·注意力机制
Brilliantwxx2 小时前
【算法从零到千】【55-58】哈希位图+常见数学运算 接口
算法
空堂与归3 小时前
用户分群找不到规律?用K-Means聚类算法自动发现数据模式
算法·机器学习·kmeans·聚类
动词ing3 小时前
【C语言】自定义函数+指针入门
c语言·开发语言·算法
重生之后端学习3 小时前
283. 移动零[简单]✅
开发语言·数据结构·算法·leetcode·职场和发展
一只小小的芙厨4 小时前
基础数论总结
笔记·学习·算法
夜不会漫长5 小时前
C++入门(1)
开发语言·c++·算法
wen_zhufeng6 小时前
IndexTTS 2.5 技术报告
人工智能·算法·机器学习
大熊背7 小时前
树莓派相机自动白平衡详解(四)
算法·树莓派·白平衡·isppipeline