从 C# 重写为 python

Rewrite from C# to python

我正在尝试将部分代码从 C# 重写为 Python。 但是在 bitwise 操作中遇到了一些问题。

这是C#代码:

private string _generateConfirmationHashForTime(long time, string tag)
    {
        time = 1459152870;
        byte[] decode = Convert.FromBase64String("TphBbTrbbVGJuXQ15OVZVZeBB9M=");
        int n2 = 8;
        if (tag != null)
        {
            if (tag.Length > 32)
            {
                n2 = 8 + 32;
            }
            else
            {
                n2 = 8 + tag.Length;
            }
        }
        byte[] array = new byte[n2];
        int n3 = 8;
        while (true)
        {
            int n4 = n3 - 1;
            if (n3 <= 0)
            {
                break;
            }
            array[n4] = (byte)time;
            time >>= 8;
            n3 = n4;
        }
        if (tag != null)
        {
            Array.Copy(Encoding.UTF8.GetBytes(tag), 0, array, 8, n2 - 8);
        }

        try
        {
            HMACSHA1 hmacGenerator = new HMACSHA1();
            hmacGenerator.Key = decode;
            byte[] hashedData = hmacGenerator.ComputeHash(array);
            string encodedData = Convert.ToBase64String(hashedData, Base64FormattingOptions.None);
            Console.WriteLine(encodedData)
            return encodedData
        }
        catch (Exception)
        {
            return null; //Fix soon: catch-all is BAD!
        }
    }

我改写成Python:

 def _generateConfirmationHashForTime(self, time, tag):
    time = 1459152870
    decode = base64.b64decode("TphBbTrbbVGJuXQ15OVZVZeBB9M=")
    n2 = 8
    if tag is not None:
        if len(tag) > 32:
            n2 = 8 + 32
        else:
            n2 = 8 + len(tag)

    arrayb = [hex(time >> i & 0xff) for i in (56, 48, 40, 32, 24, 16, 8, 0)]

    if tag is not None:
        for ch in range(0, len(tag)):
            arrayb.append(hex(ord(tag[ch])))

    arrayc = 0
    n4 = len(arrayb) - 1
    for i in range(0, len(arrayb)):
        arrayc <<= 8
        arrayc |= int(arrayb[n4], 16)
        n4 -= 1

    array_binary = binascii.a2b_hex("{:016x}".format(arrayc))
    hmacGenerator = hmac.new(decode, array_binary, hashlib.sha1)
    hashedData = hmacGenerator.digest()
    encodedData = base64.b64encode(hashedData)

    print encodedData

散列结果不相等

变量 encodedData 不匹配 :(

你能指出代码中哪里可能出错吗?

好的,现在我想起来为什么不用Python了。语言在一边,虽然...

C# 代码组成一个字节数组,8 个字节来自 time 变量(大端格式,MSB 优先),最多 32 个字节来自 tag 字符串的 UTF8 编码。 ..但受限于原始字符串的长度,忽略多字节编码。不太理想,但我们可以处理。

来自 time 变量的字节非常简单:

arr = struct.pack(">Q", time)

对于 tag 字符串,将其转换为 UTF8,然后切掉前 32 个字节并将其附加到数组中:

arr += str(tag).encode("utf-8")[0:min(32, len(str(tag)))]

到目前为止我们都很好。我将 arr 的 base64 编码与 C# 中的组合消息进行了比较,它们与我的测试数据匹配,生成的 HMAC 消息摘要也是如此。

完整代码如下:

def _generateConfirmationHashForTime(time, tag):
    time = 1459152870
    decode = base64.b64decode("TphBbTrbbVGJuXQ15OVZVZeBB9M=")

    arr = struct.pack(">Q", time) 
    arr += str(tag).encode("utf-8")[0:min(32, len(str(tag)))]

    hmacGenerator = hmac.new(decode, arr, hashlib.sha1)
    hashedData = hmacGenerator.digest()
    encodedData = base64.b64encode(hashedData)

    return encodedData