Python校验和计算思想

Python校验和计算思想,python,hash,checksum,Python,Hash,Checksum,我在excel工作表中有一个包含字符串的表,比如说3列2行。 例如: “一”、“二”、“三” “四”,“五”,“六” 我想提出一种算法,可以计算整个表的校验和,如果添加一个新行(显而易见),或者一个字符串开关与另一行的另一个字符串开关(不那么显而易见),这将是不同的 因此,下表的校验和与上表不同: “一”、“五”、“三” “四”、“二”、“六” 我知道有很多可能的方法可以实现这一点,但是在python中有没有一种干净而健壮的方法呢?我曾想过在计算中使用字符串在表中的位置作为一个因素,但我

我在excel工作表中有一个包含字符串的表,比如说3列2行。 例如:

  • “一”、“二”、“三”
  • “四”,“五”,“六”
我想提出一种算法,可以计算整个表的校验和,如果添加一个新行(显而易见),或者一个字符串开关与另一行的另一个字符串开关(不那么显而易见),这将是不同的

因此,下表的校验和与上表不同:

  • “一”、“五”、“三”
  • “四”、“二”、“六”
我知道有很多可能的方法可以实现这一点,但是在python中有没有一种干净而健壮的方法呢?我曾想过在计算中使用字符串在表中的位置作为一个因素,但我不知道这是否是一个好主意,因为校验和计算是我较弱的技能之一

我觉得我应该提到,在同一个excel文件中,我有其他数据可以更改,而无需修改校验和。校验和应该只验证上面提到的表的数据,并且必须是一个数值(因为我以后需要通过CAN总线发送它)

有人对我如何做到这一点有什么建议吗?请精确并举例说明


编辑: 因此,我提出了一个算法,但完全不确定它的鲁棒性。 我的想法是首先为第一列的每个单元格计算校验和,并将其乘以行索引,然后对第二列和第三列执行相同的操作(如果我们使用与描述中相同的表)。最后,通过将每个校验和乘以它们的列索引,对得到的校验和求和。比如:

总校验和=(校验和('1')*1+校验和('4')*2)*1+(校验和('2')*1+校验和('5')*2)*2+(校验和('3')*1+校验和('6')*2)*3

为了解释我的观点,我很乐意发布这样的计算结果,没有任何花哨的代码。现在,对于代码(目前还不太好,很抱歉),我们可以假设表内容已经解析到一个字典列表中,其中key=column,item=value。对于示例中的表格,我们有:

tab = [{"A": "one", "B": "two", "C": "three"},
       {"A": "four", "B": "five", "C": "six"}]

print str(calculate_checksum(tab))


def calculate_checksum(table):
    """Calculate checksum of a dictionary (represents the excel table)"""

    def checksum(st):
        """Convert a string into tables of ascii characters and reduce it"""
        return reduce(lambda x, y: x + y, map(ord, st))

    total_cks = column_count = 0

    # list the data of each column:
    for column in ['A', 'B', 'C']:
        data_list = [data[column] for data in tables]
        chk = 0
        for row_index in range(len(data_list)):
            chk += checksum(data_list[row_index]) * (row_index + 1) # multiply each cell's checksum by its row index

        column_count += 1
        total_cks += chk * column_count # multiply each column checksum by its column index

    return total_cks

使用这个算法,原始表的校验和是7254。当我切换“2”和“5”时,我得到7094,所以它可以工作。当我切换“一”和“二”时,我得到7230,这也包括在内

这不需要校验和

import pandas as pd
df1 = pd.read_excel("...")
df2 = pd.read_excel("...")
exact_match = df1.equals(df2)
如果值完全匹配,则精确匹配将返回
True
,否则返回
False

您可以使用来实现此目的。您所要做的就是在工作表中循环,并以字符串(或您喜欢的任何格式)存储累积数据,以便以后进行比较:

from openpyxl import Workbook, load_workbook

wb = load_workbook(filename = 'latest.xlsx')
sheet = wb["some_sheet"]
sheet_data = ""
i = 1
while sheet['a'+str(i)].value != None:
    sheet_data = sheet['a'+str(i)].value + "::" + sheet['b'+str(i)].value + "::" + sheet['c'+str(i)].value +  "\n"
    i += 1

if sheet_data != old_sheet_data: #store the old_sheet_data somewhere
    pass #not matched

您可以使用pip3或pip包管理器安装
openpyx
库。

在Prahlad Yeri的帮助下,我成功地实现了这一点。我发现我需要的是zlib图书馆

我用“:”在每个字符串之间加上所有单元格内容(可以使用被认为安全的任何其他字符),并使用zlib库的adler32函数计算出其中的32位校验和

import zlib

tab = [{"A": "one", "B": "two", "C": "three"},
   {"A": "four", "B": "five", "C": "six"}]

print str(calculate_checksum(tab))


def calculate_checksum(table):
    """Returns a 32bits checksum out of the concatenated cell contents, using Adler algorithm."""
    data = ""
    for row in table:
        for column in ["A", "B", "C"]:
            data += row[column] + ":" # Use ":" to separate each string

    return zlib.adler32(data)

你说的桌子是什么意思?它是csv文件吗?熊猫数据帧?Excel表格?只需加载并散列即可。@Ev.Kounis抱歉,我自己也不太准确。这是一张excel表格。我会更新描述的,谢谢。你说的“散列”是什么意思?你是怎么做到的?我在努力理解。是否要检查添加的新行是否是已存在的行列表中的一行?您不能简单地检查并比较excel文件的哈希吗@KrishnaSangeethKS不,我想做的是能够用校验和验证两个表是不相似的,即使其中一个项只是交换了行。如果excel文件只包含我感兴趣的表,那就行了。但是,我的excel文件包含其他工作表,这些工作表应该能够在不修改上述表的校验和的情况下进行编辑。另一件事是,我实际上需要一个校验和值,因为我想把这个值在CAN上传输到一个ECU,ECU将把它和它自己的校验和进行比较。。。为了简化这个问题,我把这些细节留给了你们。我们会更进一步的谢谢你们@Prahlad。这确实可以使用,但我仍然需要一个校验和出来。它确实需要是一个数值。当然,一旦你得到了字符串变量(
sheet\u data
),只需使用
hashlib
库来计算它的校验和,就像在这个例子中:
hashlib.sha256(“a.encode('utf-8'))。hexdigest()
参考另一个答案:你的答案引导我朝着正确的方向,谢谢你,普拉拉德。我实际上需要一个32位校验和,以便能够通过CAN总线发送它。通过查看您提供的链接并扩展研究,我发现zlib库包含我需要的内容:adler32算法,它从字符串中生成32位校验和。因此,我尝试按照您的建议,将从表中获得的所有字符串相加,并使用adler32进行校验和:它是有效的。我现在唯一的疑问是,它是否足够健壮,可以随时检测到哪怕是很小的变化:它似乎不是最可靠的算法。我应该补充一点,当你确信增加字符串不会成为问题时,这种方法是可以的。这意味着使用该方法,如果第一行中有“on”、“etwo”、“three”而不是“one”、“two”、“three”,则校验和不会改变,因为当您将它们全部相加时,将得到相同的最终字符串。