【问题标题】:Python vector(list) to 2D matrix hashPython向量(列表)到二维矩阵哈希
【发布时间】:2020-07-23 08:11:28
【问题描述】:

我有一个返回向量的函数。每个结果的向量长度不同。 例如,这些是我的函数返回的一些向量:

res_1 = [67, 68, 69, 70, 25, 71]
res_2 = [49, 45, 50, 51, 52, 53, 54, 45, 55, 56, 25, 57, 58, 59, 60, 61, 62, 63, 64, 45, 65, 58, 66, 45, 50]
res_3 = [72, 4]

我想要一个函数从向量中生成二维矩阵散列。矩阵哈希长度必须是常数。例如 50x50 或 100x100。此函数必须为每个给定向量生成一个唯一值 NxN 矩阵。

如何实现这个功能?

【问题讨论】:

    标签: python matrix hash


    【解决方案1】:

    使用零填充是个好主意,但如果您的矢量生成函数可以输出包含一个或多个零的列表,它可能不起作用。你可能会运气不好,偶然得到一个重复的向量。

    很难说,因为问题中没有太多关于向量生成函数的细节。

    无论如何,这是从列表的 SHA256 哈希中获取由二进制位组成的 16x16 矩阵的复杂方法:

    #!/usr/bin/env python3
    
    import hashlib
    import numpy as np
    import bitstring
    
    res_1 = [67, 68, 69, 70, 25, 71]
    res_2 = [49, 45, 50, 51, 52, 53, 54, 45, 55, 56, 25, 57, 58, 59, 60, 61, 62, 63, 64, 45, 65, 58, 66, 45, 50]
    res_3 = [72, 4]
    
    def hash(l):
        m = hashlib.sha256()
        m.update(bytearray(l))
        h = m.hexdigest()
        c = bitstring.BitArray(hex=h)
        b = c.bin
        a = np.frombuffer(b.encode('utf-8'), 'u1') - ord('0')
        r = np.reshape(a, (-1, 16))
        return r
    
    print(hash(res_1))
    print(hash(res_2))
    print(hash(res_3))
    

    只要列表包含不同的值,它们就应该有不同的字节表示,因此它们的 SHA256 哈希值实际上应该保证是唯一的。虽然有可能发生碰撞,但几率很小,几乎可以忽略不计。

    如果哈希冲突的可能性很小,您可能会考虑使用零填充或其他方法来执行所谓的“完美哈希”,而不是使用 SHA256。

    样本输出:

    [[1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 1 0 1 0 0 1 1 1 1 0 0 0]
     [1 0 0 1 1 0 0 1 0 1 0 1 1 0 1 0]
     [1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 0]
     [0 1 1 0 0 1 1 0 1 0 1 1 1 0 1 0]
     [1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1]
     [1 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0]
     [0 0 0 1 0 1 0 0 0 1 1 0 1 0 0 0]
     [1 1 1 1 0 1 0 1 0 0 1 1 1 1 0 1]
     [1 1 0 0 1 1 0 1 1 0 1 0 1 1 1 0]
     [1 1 1 1 0 0 0 1 0 0 1 0 1 0 0 0]
     [0 0 0 0 1 0 0 1 1 0 0 0 0 1 1 1]
     [0 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1]
     [1 0 0 1 0 1 1 1 0 1 1 1 1 1 1 0]
     [1 1 1 0 0 0 0 1 1 0 0 1 0 0 1 1]
     [0 1 0 1 1 1 1 1 1 1 0 0 1 0 0 1]]
    [[0 0 1 1 0 1 1 1 1 1 1 0 1 1 0 1]
     [0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 1]
     [0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 1]
     [0 1 0 0 0 0 1 0 1 1 0 1 0 0 1 1]
     [0 1 0 0 0 1 1 0 1 0 0 1 0 1 1 1]
     [0 1 1 1 0 1 1 1 1 1 0 1 1 1 0 1]
     [0 0 1 1 0 1 1 1 0 1 1 0 0 1 1 0]
     [0 1 0 0 0 1 1 0 0 1 0 0 1 0 0 1]
     [0 1 1 0 1 1 1 0 0 0 0 1 1 0 0 0]
     [0 1 0 1 1 1 1 1 0 1 1 1 1 1 0 0]
     [0 1 1 1 0 1 0 0 1 1 1 0 1 0 0 0]
     [1 1 1 1 0 0 1 0 0 1 0 1 0 1 1 1]
     [1 1 1 1 1 1 0 0 0 0 1 1 0 0 1 1]
     [0 1 0 1 1 1 0 0 0 1 1 1 1 0 0 1]
     [1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1]
     [0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0]]
    [[1 0 1 0 1 0 0 1 1 0 1 1 0 1 0 0]
     [1 1 0 1 0 0 0 1 0 0 1 1 1 1 1 1]
     [1 0 0 0 1 0 1 0 0 1 0 1 0 0 0 1]
     [0 1 0 1 0 1 1 0 1 0 1 0 1 1 0 0]
     [0 0 0 1 0 1 1 1 0 0 1 0 0 1 0 0]
     [0 0 0 0 1 1 0 1 1 1 1 1 1 0 1 0]
     [1 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0]
     [1 0 0 1 0 0 0 1 1 0 1 0 0 1 0 0]
     [1 0 1 1 1 0 1 1 0 1 1 0 0 1 0 1]
     [1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 1]
     [1 1 0 1 1 0 0 0 0 1 1 1 1 1 0 0]
     [1 1 0 1 0 1 1 1 0 1 0 0 1 0 0 1]
     [1 1 1 1 0 1 1 1 0 0 1 0 0 1 0 1]
     [1 1 1 0 1 1 1 1 1 0 1 1 0 0 1 1]
     [1 1 0 0 0 1 0 1 1 0 1 0 0 0 0 0]
     [1 1 0 0 0 1 1 1 0 0 1 1 0 0 1 0]]
    

    【讨论】:

      【解决方案2】:

      如果您知道 vector 的最大可能长度 (max_len),则只需用零填充向量是合乎逻辑的: vector += [0]*(max_len - len(vector))

      而不是将其设为 2D:vector2D = [vector[i:i+N] for i in range(0, max_len, N)]

      【讨论】: