在SAS中,给定每个记录的md5哈希值,为整个文件计算一个md5哈希值

时间:2019-07-18 12:16:04

标签: sas md5 checksum

这是我最近关于在SAS和python中计算md5哈希值的问题的跟进。因此,我正在使用SAS v9.2,并且有一个md5哈希函数,该函数接收字符串并返回哈希。我真正想要的是一种计算整个文件的哈希值的方法。假设我为每个记录都有一个哈希,有没有办法做到这一点,并使文件哈希与使用python代码获得的值匹配。以sashelp.shoes数据集为例,我将其导出到CSV文件,并手动删除了货币字段的双引号,美元和逗号。然后,我使用以下python代码计算了整个文件的哈希值:

filename = "f:/test/shoes.csv"
md5_hash = hashlib.md5()
with open(filename,"rb") as f:
    # Read and update hash string value in blocks of 4K
    for byte_block in iter(lambda: f.read(1024*1024),b''):
        md5_hash.update(byte_block.replace(b'\r', b'').replace(b'\n', b''))
    print(md5_hash.hexdigest())

然后将此哈希作为输出返回:

f7f205b5b844bf57f5f51685969e0df0

如果任何人都可以在SAS中为该数据集复制此最终哈希值,那就太好了。

我在SAS V9.2上使用PS

3 个答案:

答案 0 :(得分:0)

您有两个选择:

  • 在SAS中实施MD5算法。我知道SHA和CRC的现有实现,但是我不确定MD5。
  • 从SAS调用外部实用程序以计算文件的md5哈希。有一个示例here

答案 1 :(得分:0)

很遗憾,您无法使用DS1。原因是SAS允许的最大变量大小只有32,767字节长。您可以将变量分组为多个变量,但是当您尝试将它们串联时(甚至直接在调用md5函数时),它最终也会将其截断。最好的选择是将输出写入外部文本文件(如上例所示,如下所示)并在其上生成md5sum。实际上,这只是多余的一小步。您可以使用X命令从SAS本身进行操作(前提是您已配置为执行此操作)。

filename ff "contents.txt" TERMSTR=CR;

data _null_;
  set shoes end = lastrec;
  newvar2 = catx(',',&varstr2);
  file ff;
  put newvar2;
run;

答案 2 :(得分:0)

我先前关于限制的说明仅在使用DS1时适用。 DS1中没有长度限制的方法。您可以尝试这样做,并且会收到错误消息:

data test;
  length x $30000;
  x = repeat('-', 30000);
run;

data _null_;
  set test;
  format m $hex32.;
  m = md5(catx(',', x, x));
  put m=;
run;`

但是Robert Pendridge指出DS2可以解决此问题是正确的。

%let reclen = 201; /* Length of each record */
%let records = 2000; /* Number of records */
%let totlen = %eval(&reclen * &records);

proc ds2;
data _null_;
   retain m;
   dcl char(&totlen) m;
   method run();
      dcl char(200) c;
      set shoes;
      c = catx(',',&varstr2);
      m = strip(m)|| strip(c);
   end;
   method term();
      dcl char(32) hh;
      hh = put(md5(m), $hex32.);
      put hh=;
   end;
enddata;
run;
quit;

这实际上是在做Python代码正在做的事情。 update仅连接字符串并应用哈希。您可能需要稍微拧紧一点以除去多余的空间等,但是应该可以。