java - 在 Java 和 C# 中使用 SHA-1 加密 ID 时,C# 有时会返回带有额外 0 的值
问题描述
我有一个连接到另一个外部网站并传递 ID 号的网站,我正在处理并生成链接的页面是用 c# 编写的,而目标网站是用 Java 编写的,我遇到了一些不匹配
我试图在 C# 中使用与 Java 中的代码相同的方法来加密 ID,代码如下所示:
public static String shaHash(String input)
throws NoSuchAlgorithmException {
if (input == null) {
return null;
}
MessageDigest sha = MessageDigest.getInstance("SHA");
try {
sha.update(input.getBytes("UTF8"));
BigInteger hash = new BigInteger(1, sha.digest());
return hash.toString(16);
} catch (UnsupportedEncodingException e) {}
return null;
}
C# 代码看起来像
StringBuilder convertedId = new StringBuilder();
var idToByte = Encoding.ASCII.GetBytes(id);
using (SHA1 sha1 = SHA1.Create())
{
var bytes = sha1.ComputeHash(idToByte);
for (int i = 0; i < bytes.Length; i++)
{
convertedId.Append(bytes[i].ToString("x2"));
}
}
return convertedId.ToString();
但是返回值是不同的,因为 C# 代码似乎在开头添加了一个额外的 0:
Java:b83caf2f739209c42a8d02df0f6d4794f288703,C#:0b83caf2f739209c42a8d02df0f6d4794f288703
这会是什么问题?我试图更改 UTF8 的 C# 代码中的编码,但仍然无法正常工作。
有什么想法吗?
提前谢谢了
解决方案
问题是,你想要额外的 0 还是不想要?
十六进制输出通常以每个字节 2 个十六进制数字完成,因此您会得到偶数位,即前导 0 通常是您想要的。
JavaBigInteger
没有这样做,因为对它来说,输出是 base-16 number,而不是bytes的十六进制编码。
因此,与其在 C# 中删除多余的 0,不如在 Java 中添加前导 0。
如果结果字符串的长度为奇数(例如),您可以继续使用BigInteger
但在前面加上 a ,或者使用其他一些十六进制编码的.
请参阅如何在 Java 中将字节数组转换为十六进制字符串?0
s.length() % 2 != 0
byte[]
推荐阅读
- c# - 如何填写文本框?
- amazon-web-services - 连接 AWS Api Gateway 和私有 ALB
- android - 如果 Firestore 数据库发生变化,我是否会再次阅读所有文档?
- python-3.x - 在打包机器人中获取客户端位置
- python - readlines 函数在应用于从网页响应获得的文件时抛出错误
- java - 为什么数组类型的类变量在声明后无法初始化,但可以在Java中的方法内部初始化?
- javascript - Photoshop JavaScript (ExtendScript):如何在脚本完成之前显示图层?
- rxjs - Visual Studio AppCenter 构建失败,Bash 以代码“1”退出
- c++ - 为同一向量 C++ 运行多个线程时出现分段错误
- matlab - 在 MATLAB 中将坐标显示为 surf