1
votes

Dans SAS, calculez un hachage md5 pour le fichier entier étant donné que vous avez un hachage md5 pour chaque enregistrement

Ceci fait suite à ma question récente sur le calcul du hachage md5 en SAS et python. Donc, j'utilise SAS v9.2 et il existe une fonction de hachage md5 qui prend une chaîne et renvoie un hachage. Ce que j'aimerais vraiment, c'est un moyen de calculer le hachage du fichier dans son ensemble. Étant donné que j'ai un hachage pour chaque enregistrement, existe-t-il un moyen de le faire et de faire correspondre le hachage du fichier avec la valeur obtenue en utilisant, par exemple, du code python. En prenant le jeu de données sashelp.shoes comme exemple, je l'ai exporté dans un fichier CSV et j'ai supprimé manuellement les guillemets doubles, les dollars et les virgules des champs de devise. J'ai ensuite calculé le hachage pour le fichier dans son ensemble en utilisant ce code python:

f7f205b5b844bf57f5f51685969e0df0

Et j'ai récupéré ce hachage en sortie:

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())

Si quelqu'un peut répliquer cette valeur de hachage finale dans SAS pour cet ensemble de données, ce serait génial.

PS Je suis sur SAS V9.2


1 commentaires

Si votre fichier est inférieur à 32k octets, vous pouvez le faire dans un fichier de données normal car les variables de caractères sont (toujours!) Limitées à 32767 caractères. Sinon, vous pourrez peut-être le faire avec proc ds2 qui autorise plus de types de données (y compris des chaînes plus longues).


3 Réponses :


0
votes

Vous avez deux options:

  • Implémentez l'algorithme MD5 dans SAS. Je connais les implémentations existantes pour SHA et CRC, mais je ne suis pas sûr de MD5.
  • Appelez un utilitaire externe de SAS pour calculer le hachage md5 du fichier. Il existe un exemple ici .

3 commentaires

Le deuxième choix n'est pas une option car cela me donnerait un hachage pour le format interne SAS de l'ensemble de données. Les données de l'ensemble de données seront finalement transférées sous forme de fichier texte vers AWS. Je voulais le hachage afin de vérifier que les données que nous extrayons de SAS et ce qui se termine dans AWS sont les mêmes. Quant à votre premier point, SAS a déjà une fonction MD5. Cependant, il ne fonctionne que sur une chaîne de caractères. Je peux calculer le hachage md5 pour chaque ligne de l'ensemble de données. Je me suis demandé si je pouvais vous en servir pour calculer un hachage md5 pour l'ensemble de données dans son ensemble


Êtes-vous plus préoccupé par les différences entre les données extraites de SAS et l'ensemble de données SAS d'origine, ou par les erreurs introduites lors du transit vers AWS? Vous pouvez écarter ce dernier beaucoup plus facilement en hachant le fichier exporté avant et après le téléchargement à l'aide d'un utilitaire externe.


@ user2699504 Comment le transférez-vous vers AWS? Vous utilisez l'AWS CLI? Vous essayez peut-être de résoudre un problème qui n'a pas besoin d'être résolu car ils valident quand même les sommes de contrôle des fichiers après les téléchargements: docs.aws.amazon.com/cli/latest/topic/s3-faq.html



0
votes

Malheureusement, vous ne pouvez pas dans DS1. La raison en est que la taille maximale de variable autorisée par SAS n'est que de 32 767 octets. Vous pouvez regrouper les variables en plusieurs variables, mais quand vous essayez de les concaténer (même directement lors de l'appel de la fonction md5), cela finira par la tronquer. Votre meilleur pari est d'écrire la sortie dans un fichier texte externe (comme indiqué ci-dessous sur la base de votre exemple précédent) et de générer md5sum dessus. Il ne s'agit en fait que d'une petite étape supplémentaire. Vous pouvez simplement utiliser la commande X pour le faire depuis SAS lui-même (à condition que vous soyez configuré pour le faire).

filename ff "contents.txt" TERMSTR=CR;

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


0 commentaires

0
votes

Ma note précédente sur les limitations s'applique uniquement lorsque je travaille avec DS1. Il n'y a aucun moyen de contourner la restriction de longueur dans DS1. Vous pouvez essayer ceci et vous obtiendrez une erreur:

%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;

Mais Robert Pendridge a raison de souligner que DS2 peut résoudre ce problème.

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

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

C'est essentiellement ce que fait le code Python. La update concatène simplement les chaînes et applique le hachage. Vous devrez peut-être resserrer un peu cela pour supprimer les espaces superflus, etc., mais cela devrait fonctionner.


0 commentaires