Hacher une chaîneJe veux une fonction de hachage dans JMP pour les chaînes courtes. (J'en ai besoin pour créer des clés de base de données entières anonymisées à partir de données de ligne.)
Il n'est pas nécessaire qu'il soit de qualité cryptographique, il doit simplement avoir un résultat de 64 bits (ou 128 bits) et un taux de collision raisonnablement faible. J'ai essayé d'utiliser Blob MD5() (avec troncature à 64 bits), mais je n'arrive pas à croire à quel point c'est lent. (Essayez-le simplement sur une table de 500 000 lignes !).Quelqu'un a-t-il créé ou lié à un algorithme de hachage rapide en JSL ? Qu'en est-il de l'ensemencement du générateur de nombres aléatoires de JSL avec une fonction de la chaîne d'entrée ? Je n'ai pas besoin de la qualité NIST, mais j'ai besoin de quelque chose de rapide et pas très sale qui donnera le même résultat sur toutes les plateformes.
Pouvez-vous appeler depuis JSL l'un des nombreux algorithmes de hachage C++ ou Java disponibles ? Comment?
PS Peut-être que JMP 14.1 pourrait inclure de meilleures fonctions de hachage dans sa bibliothèque standard. Et si vous incluiez SHA ?
Re : Hacher une chaîneAu fait, voici la solution que j'ai finalement retenue :
// ==========================
// ::String Hash()
// ==========================
myStringHash = New Custom Function(
"Global",
"String Hash",
Function( {str, length = 64},
{bytes},
bytes = Match( length, 64, 8, 32, 4, Throw( "Bad argument in ::String Hash; hash length must be 64 (default) or 32." ) );
Subscript( Blob To Matrix( Blob Peek( Blob MD5( Char To Blob( str, "utf-8" ) ), 0, bytes ), "int", bytes, "little" ), 1 );
)
);
myStringHash << Description(
"Accepts a string as input, and returns an unsigned 64-bit or 32-bit integer hash of the string, generated by truncation of the (128-bit) MD5 hash of the input string.
The first parameter is the input string to be hashed.
The second, optional parameter is either the number 64 or the number 32. This selects whether the result will be a 64-bit (8-byte) integer, or a 32-bit (4-byte) integer. If not specified, the function defaults to 64-bit (8-byte). If a value other than 64 or 32 is entered, an error results."
);
myStringHash << Prototype( "::String Hash (string, <64|32>)" );
myStringHash << Example( "z = ::String Hash ( \!"This is a string\!" ); Show ( Format( z, 20, 0) )" );
myStringHash << Parameter( "String", "Input string" );
myStringHash << Parameter( "Number", "<64 or 32 (default is 64)>" );
myStringHash << Formula Category( "Database" );
Add Custom Functions( {myStringHash} );Re : Hacher une chaîneCraige,
Peut-être que j'étais trop dur avec Blob MD5. C'est plus lent que ça sur ma machine avec mes chaînes d'entrée. Merci néanmoins pour le contrôle objectif.
John
Re : Hacher une chaîneCela s'exécute en 10 secondes environ sur 1 000 000 de lignes.
start = Tick Seconds();
dt = New Table( "Untitled",
Add Rows( 1e6 ),
New Column( "Column 1", Numeric, "Continuous", Format( "Best", 12 ), Formula( Row() ) ),
New Column( "Column 2", Character, "Nominal", Formula( Hex( Blob MD5( Char To Blob( Char( :Column 1 ) ) ) ) ) )
);
dt << runformulas; // run the formulas now, not in the background
stop = Tick Seconds();
Show( stop - start );
Using MD5 for hashUsing MD5 for hashUtiliser MD5 pour le hachage
Re : Hacher une chaîneMerci pour cette solution !
Malheureusement, je suis sur Mac, je ne peux donc pas utiliser VBS. Mais maintenant, je vois dans votre exemple comment utiliser RunProgram, et je vais essayer de le faire fonctionner pour CityHash ( https://opensource.googleblog.com/2011/04/introducing-cityhash.html ).
Re : Hacher une chaîneJohn_Madden,
Je ne suis pas un expert et cela pourrait ne pas répondre à vos besoins. Vous trouverez ci-dessous un VBscript pour le cryptage SHA256 et MD5. Trouvez-le ici sur ce lien.
https://gist.github.com/jermity/557de47a978f7a7c4a74
Je ne connais que Windows.Copiez le fichier joint et modifiez l'extension en .vbs. Ouvrez une fenêtre de commande, accédez au répertoire de sauvegarde et tapez jerhash.vbs pour obtenir la syntaxe d'utilisation.Le script intégré convertit les noms d'état. Ce script vbs ne semble pas autoriser une liste de valeurs. Les 52 noms d'état ont pris 8,2 secondes, et je suis sûr que la surcharge liée à la connexion du programme d'exécution s'ajoute à cela. Le script ci-joint montre une autre méthode de création d'un fichier .bat. cela a pris en moyenne environ 0,1 seconde pour les 52 éléments. Je n'ai pas lu le fichier. C'est une autre approche. Générez les 500 000 hors ligne puis lisez le fichier.
C'est tout ce que j'ai.Salutations.

mytbl = New Table("testit", New Column("States", Character,
Values({"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut",
"District of Columbia", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
"Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine",
"Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri",
"Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon",
"Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee",
"Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin",
"Wyoming"}) ), NewColumn("Code",Character)
);
t1 = tick seconds();
for(i=1, i<=nrow(mytbl), i++,
:Code[i] = Trim(RunProgram(Executable("cscript"),
Options(EvalInsert("\[//nologo c:\temp\jerhash.vbs /A:sha256 /S:"^:States[i]^"]\") ),
ReadFunction("text")
));
);
t2= tickseconds();
show(t2-t1);