SHA1从Python转换为C#

0 投票
3 回答
1456 浏览
提问于 2025-04-17 12:07

我有一段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 个回答

1

尽量不要使用 Encoding.Default(你知道它是什么吗?)而是使用你知道另一个(Python)部分在用的编码,比如 Encoding.UTF8

否则我们可能需要看看你的 Base32.ToBase32String 代码,看看输入或输出是否有不同。

1

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'));
2

你提到的代码来自 atrevido.net,实际上不能生成你描述的输出(D1CD...),因为那段代码根本没有使用字符 1(你可以看看它的 ValidChars 常量,里面用的是一种非常不标准的 base32 字符集,其中缺少了 10)。

实际上,你给出的 C# 输出字符串只包含字符 0-9A-F,这让我觉得它是十六进制的。根据这个,Python 中的代码 hashlib.sha1('user@me.com').hexdigest().upper() 生成的输出,实际上就是你从 C# 得到的字符串... D1CDF40BB39DB82315DD515A93CE160C3FB5FA2B

所以问题在于,你在 .Net 下使用的代码并没有进行任何类型的 base32 编码,而是使用了 base16 / 十六进制编码。你需要在 Python 中使用十六进制,或者在 .Net 中使用真正的 base32 实现。

(另外,正如其他人所建议的,你应该使用 Encoding.UTF8.GetBytes,否则在不同的电脑上可能会出现不一致的行为)。

撰写回答