Python校验和计算思想
我在excel工作表中有一个包含字符串的表,比如说3列2行。 例如:Python校验和计算思想,python,hash,checksum,Python,Hash,Checksum,我在excel工作表中有一个包含字符串的表,比如说3列2行。 例如: “一”、“二”、“三” “四”,“五”,“六” 我想提出一种算法,可以计算整个表的校验和,如果添加一个新行(显而易见),或者一个字符串开关与另一行的另一个字符串开关(不那么显而易见),这将是不同的 因此,下表的校验和与上表不同: “一”、“五”、“三” “四”、“二”、“六” 我知道有很多可能的方法可以实现这一点,但是在python中有没有一种干净而健壮的方法呢?我曾想过在计算中使用字符串在表中的位置作为一个因素,但我
- “一”、“二”、“三”
- “四”,“五”,“六”
- “一”、“五”、“三”
- “四”、“二”、“六”
编辑: 因此,我提出了一个算法,但完全不确定它的鲁棒性。 我的想法是首先为第一列的每个单元格计算校验和,并将其乘以行索引,然后对第二列和第三列执行相同的操作(如果我们使用与描述中相同的表)。最后,通过将每个校验和乘以它们的列索引,对得到的校验和求和。比如: 总校验和=(校验和('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”,则校验和不会改变,因为当您将它们全部相加时,将得到相同的最终字符串。