在 SAS v python 代码和 CSV 文件中创建的数据集 md5 哈希的差异
Difference in dataset md5 hash created in SAS v python code and CSV file
帖子数:1
md5哈希问题
选项
9m 前
大家好,我是 SAS 新手,在以下问题上需要一些帮助。我正在试验 md5 哈希函数并在 sashelp.shoes 数据集上对其进行测试。
在数据步中,对于每个输入观察,我正在创建一个新变量,它是使用 catx 和逗号作为字段分隔符的每个字段的串联。然后,我将该变量用作 md5 函数的输入,果然我得到了一个散列值,我使用 PUT 将其打印到日志中。我为每条输入线重复了这个。然而,我随后将鞋子数据集导出到 CSV 文本文件。导出用双引号将字段括起来,并为我从 CSV 文件中手动删除的货币字段包含 $ 和逗号。所以从视觉上看,CSV 的行看起来与 SAS 输出的行完全一样。接下来,我编写了一个 python 脚本来读取 CSV 文本文件的每一行并为其计算 md5 哈希值。不幸的是,CSV 文件的哈希值 none 与 SAS 的哈希值匹配。有没有人做过类似的事情,如果有,你能告诉我哪里出错了。我知道 python 代码是正确的,因为我使用 windows.
中的内置 md5 检查器检查了结果
明天我再次上班时,如果有帮助,我将 post 使用一些我正在使用的代码。同时,如果有人可以提供帮助,我们将不胜感激
我正在使用企业指南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 端的 newlines/linefeeds 有关,因此更改了我的代码以仅单独查看第一个输入字符串。
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
差异来自空格。如果你在 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;
这给出:
现在,当我将其修改为(注意删除连接字符串两边所有额外空格的附加 strip 函数)时:
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
帖子数:1 md5哈希问题 选项 9m 前
大家好,我是 SAS 新手,在以下问题上需要一些帮助。我正在试验 md5 哈希函数并在 sashelp.shoes 数据集上对其进行测试。
在数据步中,对于每个输入观察,我正在创建一个新变量,它是使用 catx 和逗号作为字段分隔符的每个字段的串联。然后,我将该变量用作 md5 函数的输入,果然我得到了一个散列值,我使用 PUT 将其打印到日志中。我为每条输入线重复了这个。然而,我随后将鞋子数据集导出到 CSV 文本文件。导出用双引号将字段括起来,并为我从 CSV 文件中手动删除的货币字段包含 $ 和逗号。所以从视觉上看,CSV 的行看起来与 SAS 输出的行完全一样。接下来,我编写了一个 python 脚本来读取 CSV 文本文件的每一行并为其计算 md5 哈希值。不幸的是,CSV 文件的哈希值 none 与 SAS 的哈希值匹配。有没有人做过类似的事情,如果有,你能告诉我哪里出错了。我知道 python 代码是正确的,因为我使用 windows.
中的内置 md5 检查器检查了结果明天我再次上班时,如果有帮助,我将 post 使用一些我正在使用的代码。同时,如果有人可以提供帮助,我们将不胜感激
我正在使用企业指南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 端的 newlines/linefeeds 有关,因此更改了我的代码以仅单独查看第一个输入字符串。
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
差异来自空格。如果你在 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;
这给出:
现在,当我将其修改为(注意删除连接字符串两边所有额外空格的附加 strip 函数)时:
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