SHA1从Python转换为C#
我有一段Python代码,想把它转换成C#。但是C#的结果和Python的不一样。有人能解释一下这段代码在做什么吗?有没有什么建议可以帮助我把它转换成C#?
输入是:user@me.com
Python代码:
def encode_username(u):
d = hashlib.sha1(u).digest()
return base64.b32encode(d).lower()
结果:'2hg7ic5ttw4cgfo5kfnjhtqwbq73l6rl'
我的C#代码:
string EncodeUsername(string username)
{
var sh = SHA1.Create();
var bytes = sh.ComputeHash(Encoding.Default.GetBytes(username));
return Base32.ToBase32String(bytes);
}
结果:'D1CDF40BB39DB82315DD515A93CE160C3FB5FA2B'
Base32参考链接:http://www.atrevido.net/blog/PermaLink.aspx?guid=debdd47c-9d15-4a2f-a796-99b0449aa8af
3 个回答
尽量不要使用 Encoding.Default
(你知道它是什么吗?)而是使用你知道另一个(Python)部分在用的编码,比如 Encoding.UTF8
。
否则我们可能需要看看你的 Base32.ToBase32String
代码,看看输入或输出是否有不同。
C#
private static SHA1CryptoServiceProvider SHA = new SHA1CryptoServiceProvider();
private static string CalculateSHA1(string text, Encoding enc)
{
byte[] buffer = enc.GetBytes(text);
return BitConverter.ToString(SHA.ComputeHash(buffer)).Replace("-", "");
}
Python
def encode_username(u):
return hashlib.sha1(u.encode('utf-8'));
你提到的代码来自 atrevido.net,实际上不能生成你描述的输出(D1CD...
),因为那段代码根本没有使用字符 1
(你可以看看它的 ValidChars
常量,里面用的是一种非常不标准的 base32 字符集,其中缺少了 1
和 0
)。
实际上,你给出的 C# 输出字符串只包含字符 0-9A-F
,这让我觉得它是十六进制的。根据这个,Python 中的代码 hashlib.sha1('user@me.com').hexdigest().upper()
生成的输出,实际上就是你从 C# 得到的字符串... D1CDF40BB39DB82315DD515A93CE160C3FB5FA2B
。
所以问题在于,你在 .Net 下使用的代码并没有进行任何类型的 base32 编码,而是使用了 base16 / 十六进制编码。你需要在 Python 中使用十六进制,或者在 .Net 中使用真正的 base32 实现。
(另外,正如其他人所建议的,你应该使用 Encoding.UTF8.GetBytes
,否则在不同的电脑上可能会出现不一致的行为)。