帖子:1 md5哈希问题 选件 9m以前
大家好,我是SAS新手,需要解决以下问题。我正在尝试使用md5哈希函数,并在sashelp.shoes数据集上对其进行测试。
在数据步骤中,对于每个输入观察值,我正在创建一个新变量,该变量是使用catx和逗号作为字段分隔符的每个字段的连接。然后,我将该变量用作md5函数的输入,并且可以肯定的是,我获得了一个哈希值,可以使用PUT将其打印到日志中。我为每条输入线重复了这一步骤。但是,然后我将鞋子数据集导出到CSV文本文件。导出将字段括在双引号中,并包含我从CSV文件中手动删除的货币字段的$和逗号。因此,从视觉上看,CSV的行看起来就像是SAS输出的行。接下来,我编写了一个小python脚本来读取CSV文本文件的每一行,并为此计算md5哈希值。不幸的是,CSV文件的哈希没有一个与SAS的哈希匹配。有没有人做过类似的事情,如果可以,你能告诉我我要去哪里了。我知道python代码是正确的,因为我在Windows中使用内置的md5检查器检查了结果。
明天明天再次上班时,如果有帮助,我会发布一些我正在使用的代码。同时,如果有人可以提供帮助,将不胜感激
我正在使用企业指南V4.3
如所承诺的,这是我正在使用的SAS代码以及我得到的前几个输出记录。
/* concatenate all fields of a dataset and compute a checksum */
proc sql;
select name into :varstr2 separated by ','
from dictionary.columns
where libname = "SASHELP" and
memname = "SHOES";
quit;
data stuff(drop=check all);
format check $hex32.;
set sashelp.shoes end=end1;
newvar2 = catx(',',&varstr2);
all = catx(',',&varstr2);
check = md5(all);
put all;
put check;
run;
Africa,Boot,Addis Ababa,12,29761,191821,769
0F7503F59119E8248D89ED645F886871
Africa,Men's Casual,Addis Ababa,4,67242,118036,2284
8066D31E7C2A254EAB127C121B526DF7
Africa,Men's Dress,Addis Ababa,7,76793,136273,2433
653E4A1DF8B5708DF9C8B97587A1E981
Africa,Sandal,Addis Ababa,10,62819,204284,1861
D59E63E5319B4E3018F28D46A4CED9F9
Africa,Slipper,Addis Ababa,14,68641,279795,1771
1612FC1FE23B55078B7693ECE1E6D028
现在这是python代码和我为此得到的相同输出记录:
import hashlib
filename = "f:/test/shoes.csv"
md5_hash = hashlib.md5()
with open(filename,"r") as f:
for x in f:
result=hashlib.md5(x.encode('utf-8'))
print (x)
print(result.hexdigest())
Africa,Boot,Addis Ababa,12,29761,191821,769
7001aaebd146b10aaed951cb692c6c4b
Africa,Men's Casual,Addis Ababa,4,67242,118036,2284
916a0c39554b70d691d03c71e8daa763
Africa,Men's Dress,Addis Ababa,7,76793,136273,2433
ea9e85e9843d3bb02206bc0ba7c3d5d4
Africa,Sandal,Addis Ababa,10,62819,204284,1861
5865cfc5d443b5a2e0038c573b5b6fb9
Africa,Slipper,Addis Ababa,14,68641,279795,1771
0226115fb928f326044ca43e186ae23a2
更新。我当时认为这可能与python上的换行符/换行符有关,因此更改了我的代码,使其仅以隔离方式查看第一个输入字符串。
import hashlib
x="Africa,Boot,Addis Ababa,12,29761,191821,769"
md5_hash = hashlib.md5()
result=hashlib.md5(x.encode('utf-8'))
print (x)
print(result.hexdigest())
Africa,Boot,Addis Ababa,12,29761,191821,769
65d38fa13c098fc3959b1eb0c19b0427
Hmmm, still doesn't match with the SAS version
答案 0 :(得分:1)
差异来自空格。如果您在SAS中有一个字符串,定义为长10个字符,并且仅分配了一个仅5个字节长的字符串,那么该变量中仍然会有5个多余的空格。
例如:
data sha256 (obs = 2);
set sashelp.shoes;
concatenated = strip(Region) || strip(Product) || strip(Subsidiary) || strip(put(Stores,8.));
shahash = lowcase(put(sha256(concatenated), $hex64.));
run;
这给出了:
现在,当我将其修改为(请注意附加的删除功能,该功能删除了连接字符串两侧的所有多余空格):
data md5;
set sashelp.shoes (obs = 2);
concatenated = strip(Region) || strip(Product) || strip(Subsidiary) || strip(put(Stores,8.));
shahash = lowcase(put(sha256(strip(concatenated)), $hex64.));
run;
这给出了:
所连接变量的长度为59个字节(区域中的25个+产品中的14个+子公司中的12个+商店中的8个)。但是,由于它们的确切内容,不同的记录长度有所不同。在连接的字符串上加上strip会导致仅在确切内容上生成哈希。这与Python匹配:
comb = [b"AfricaBootAddis Ababa12", b"AfricaMen's CasualAddis Ababa4"]
for item in comb:
print(str(sha256(item).hexdigest()))
62e548b48b547b8dd112f1440d55db70fd8219e864f571ec58a84400efdba0c0
7b1f64aca891316fd7047d4b39917ee625668c26507b70358c3927f066938ecd