【问题标题】:Python - How to break word into 64bit chunksPython - 如何将单词分成 64 位块
【发布时间】:2015-12-17 14:33:24
【问题描述】:

我正在执行一项任务,我必须建立 Diffie-Helman 密钥交换。为了加快速度,我在 Python 中使用了位运算符,并且一切都在编程方面运行良好,但我必须执行奇偶校验和,而且我认为我对这是什么或如何正确理解它有效。

基本上,我需要能够获取可变长度(最多 2048 位)的密钥,将其分解为 64 位字,然后执行校验和。我不确定这到底意味着什么。要使用 Python 将一个单词分解为 64 位单词,该怎么做呢?我想一旦我这样做了,我应该能够对单词执行 XOR 操作以获得 64 位输出。目前,虽然我被困在如何在 Python 中正确地将一个单词分解为 64 位块?

【问题讨论】:

  • 不相关:这听起来不对:“为了加快速度,我在 Python 中使用位运算符” -- 位运算不是加速 Python 代码(你想要the opposite as a rule: less Python operations on more data at a time)。
  • 你输入的intbytes的类型是什么?
  • JF,是的,您可能是对的,但是我们不允许使用 pow() 函数,并且与使用 bit- 相比,在 python 中执行类似 2**256 的操作需要很长时间明智的经营者。输入的类型是 int。
  • 这是相反的任务:How to combine two 32-bit integers into one 64-bit integer?。它应该让您了解如何从 64 位整数密钥中截取 32 位整数块并从那里继续(从 2048 位密钥中截取 64 位块)。
  • 我认为将某些内容分解为位的最佳方法是将整数转换为二进制,然后我是否只是将其拆分为 64 个长度的块?是这么简单还是我错过了什么?

标签: python


【解决方案1】:

奇偶校验和只是字中所有位的异或。最有效的方法是使用 log(nbits) 操作,因为您可以将每次迭代处理的位数减半。例如:

def parity(word, nbits):
    if nbits & (nbits - 1):
        raise ValueError("nbits must be power of two")

    while nbits > 1:
        nbits >>= 1
        word ^= (word >> nbits)
    return word & 1

longitudinal 奇偶校验有点不同,因为当您达到给定字长时您会停止,此时您的奇偶校验应该全为零或全一,而不是单个一或零。我不知道你是要奇偶校验还是偶校验,所以这个比较笼统:

def longitudinal_parity(data, total_bits, word_bits, expected_parity=1):
    """
    Performs longitudinal parity check
    """
    for nbits in (total_bits, word_bits):
        if nbits & (nbits - 1):
            raise ValueError("bit size must be power of two")

    mask = (1 << total_bits) - 1

    while total_bits > word_bits:
        total_bits >>= 1
        data ^= (data >> total_bits)
        mask >>= total_bits
        data &= mask
    return data == (mask if expected_parity else 0)

因此,对于您的示例,第一个参数是 2048 位整数,total_bits 是 2048,word_bits 是 64,所需的奇偶校验是 0 或 1。

我对 Diffie-Hellman 的奇偶校验一无所知,但如果您的奇偶校验是单独提供的(似乎很可能),那么您是在与一个 单独 奇偶校验字进行比较,而不是全部或全部零。这是一个小调整:

def longitudinal_parity(data, total_bits, word_bits, expected_parity):
    """
    Performs longitudinal parity check
    """
    for nbits in (total_bits, word_bits):
        if nbits & (nbits - 1):
            raise ValueError("bit size must be power of two")

    mask = (1 << total_bits) - 1

    while total_bits > word_bits:
        total_bits >>= 1
        data ^= (data >> total_bits)
        mask >>= total_bits
        data &= mask
    return data == expected_parity

这里有很多可能的优化,例如预先计算掩码,以较小的数字开始掩码等。希望代码可读。

【讨论】:

  • 您可以明确检查 2 的幂并引发 ValueError: is_power_of_2 = lambda n: (n &gt; 0) and (n &amp; (n - 1)) == 0(注意:不包括零)。
  • 我考虑过这一点,并且还考虑过通过找到下一个较低的 2 次方并开始使用更少的位(例如使用 log 函数)来允许非 2 的幂。根据需要,将任何一个添加到生产代码中都是一件好事,但我想我会添加您的建议,以便他们知道如果引发异常他们需要做另一个:-)
  • 谢谢伙计,还没有实现,但你的解释和细节很棒。在我做任何其他事情之前,我会再读一些书,但真的很感谢你所做的一切!
猜你喜欢
  • 2015-02-12
  • 1970-01-01
  • 2014-07-02
  • 1970-01-01
  • 2023-04-05
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
相关资源
最近更新 更多