将 C# SHA256 哈希转换为 Ruby
Convert C# SHA256 hash to Ruby
我有 C# 代码:
byte[] bytes = new UnicodeEncoding().GetBytes(input);
return Convert.ToBase64String(new SHA256Managed().ComputeHash(bytes));
将字符串编码为 SHA2 哈希,然后对其进行 base 64 编码。我需要将其转换为 Ruby.
我尝试了几种方法。这是其中之一:
hash = Digest::SHA256.digest(val.encode('utf-8'))
encoded = Base64.urlsafe_encode64(hash)
我的代码都产生了不匹配的相同结果。我无法让他们工作。任何有关转换此内容的帮助将不胜感激。
更新
经过一番折腾后,我能够让它与硬编码数组一起工作,问题是 C# 代码在数组中的每个元素之后添加了一个 0。这是工作 ruby 代码(带有硬编码数组):
Digest::SHA256.base64digest([99,0,104,0,97,0,100,0].pack('C*').force_encoding('utf-16'))
我想我可以遍历数组,但这似乎没有必要。
我认为你应该将 new UnicodeEncoding()
更改为 new UTF8Encoding()
或者只使用 Encoding.UTF8
Unicode 在 C# 中是 UTF-16
K 所以这是很多项目。在 C# 中,UnicodeEncoding().GetBytes(str)
显然在字节数组的每个字符后添加了一个 0。所以我不得不在 Ruby 中解决这个问题。幸运的是,我能够使用一点 ruby 魔法来做到这一点。完整的工作解决方案如下。
byte_array = input.bytes.zip(input.bytes.map{|b| 0}).flatten.compact
Digest::SHA256.base64digest(byte_array.pack('C*').force_encoding('utf-16'))
这给了我一个与数据库中的值匹配的相同哈希输出。
解法:
您需要使用 UTF-16LE
编码来获得相同的 SHA-256 哈希值
p hash = Digest::SHA256.base64digest("Hello".encode('UTF-16LE'))
我怎么找到的?
我使用 Online C# Tool 使用以下代码创建字符串 "Hello"
的散列:
using System.IO;
using System;
using System.Text;
using System.Security.Cryptography;
class Program
{
static void Main()
{
byte[] bytes = new UnicodeEncoding().GetBytes("Hello");
String s = Convert.ToBase64String(new SHA256Managed().ComputeHash(bytes));
Console.WriteLine(s);
}
}
以上程序产生了输出oH5Pc0MkbIKybzLlb4VBjVGNiy8trnfx1W/nr1Dbl68=
然后,我编写了一个 Ruby 程序来计算字符串 "Hello"
的 Base64 编码 SHA-256 哈希值,方法是将字符串编码为 Ruby 的所有支持的字符编码以找出哪种字符编码会给出完全相同的结果。
require "digest/sha2"
require "base64"
s = "Hello"
Encoding.list.each { |e| puts "Encoding: #{e.to_s} => Hash: #{Digest::SHA256.base64digest(s.encode(e)) rescue "error"}"}
在 运行 程序之后,我得出结论,如果你使用 UTF-16LE
编码,你将得到完全相同的输出。
p hash = Digest::SHA256.base64digest("Hello".encode('UTF-16LE'))
根据documentation of UnicodeEncoding
,它:
Represents a UTF-16 encoding of Unicode characters.
我有 C# 代码:
byte[] bytes = new UnicodeEncoding().GetBytes(input);
return Convert.ToBase64String(new SHA256Managed().ComputeHash(bytes));
将字符串编码为 SHA2 哈希,然后对其进行 base 64 编码。我需要将其转换为 Ruby.
我尝试了几种方法。这是其中之一:
hash = Digest::SHA256.digest(val.encode('utf-8'))
encoded = Base64.urlsafe_encode64(hash)
我的代码都产生了不匹配的相同结果。我无法让他们工作。任何有关转换此内容的帮助将不胜感激。
更新
经过一番折腾后,我能够让它与硬编码数组一起工作,问题是 C# 代码在数组中的每个元素之后添加了一个 0。这是工作 ruby 代码(带有硬编码数组):
Digest::SHA256.base64digest([99,0,104,0,97,0,100,0].pack('C*').force_encoding('utf-16'))
我想我可以遍历数组,但这似乎没有必要。
我认为你应该将 new UnicodeEncoding()
更改为 new UTF8Encoding()
或者只使用 Encoding.UTF8
Unicode 在 C# 中是 UTF-16
K 所以这是很多项目。在 C# 中,UnicodeEncoding().GetBytes(str)
显然在字节数组的每个字符后添加了一个 0。所以我不得不在 Ruby 中解决这个问题。幸运的是,我能够使用一点 ruby 魔法来做到这一点。完整的工作解决方案如下。
byte_array = input.bytes.zip(input.bytes.map{|b| 0}).flatten.compact
Digest::SHA256.base64digest(byte_array.pack('C*').force_encoding('utf-16'))
这给了我一个与数据库中的值匹配的相同哈希输出。
解法:
您需要使用 UTF-16LE
编码来获得相同的 SHA-256 哈希值
p hash = Digest::SHA256.base64digest("Hello".encode('UTF-16LE'))
我怎么找到的?
我使用 Online C# Tool 使用以下代码创建字符串 "Hello"
的散列:
using System.IO;
using System;
using System.Text;
using System.Security.Cryptography;
class Program
{
static void Main()
{
byte[] bytes = new UnicodeEncoding().GetBytes("Hello");
String s = Convert.ToBase64String(new SHA256Managed().ComputeHash(bytes));
Console.WriteLine(s);
}
}
以上程序产生了输出oH5Pc0MkbIKybzLlb4VBjVGNiy8trnfx1W/nr1Dbl68=
然后,我编写了一个 Ruby 程序来计算字符串 "Hello"
的 Base64 编码 SHA-256 哈希值,方法是将字符串编码为 Ruby 的所有支持的字符编码以找出哪种字符编码会给出完全相同的结果。
require "digest/sha2"
require "base64"
s = "Hello"
Encoding.list.each { |e| puts "Encoding: #{e.to_s} => Hash: #{Digest::SHA256.base64digest(s.encode(e)) rescue "error"}"}
在 运行 程序之后,我得出结论,如果你使用 UTF-16LE
编码,你将得到完全相同的输出。
p hash = Digest::SHA256.base64digest("Hello".encode('UTF-16LE'))
根据documentation of UnicodeEncoding
,它:
Represents a UTF-16 encoding of Unicode characters.