J'ai besoin de convertir des chaînes en une forme de hachage. Est-ce possible en JavaScript?
Je n'utilise pas de langage côté serveur, je ne peux donc pas le faire de cette façon.
J'ai besoin de convertir des chaînes en une forme de hachage. Est-ce possible en JavaScript?
Je n'utilise pas de langage côté serveur, je ne peux donc pas le faire de cette façon.
Réponses:
Object.defineProperty(String.prototype, 'hashCode', {
value: function() {
var hash = 0, i, chr;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
});
Source: http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
hash << 5 - hash
la même chose hash * 31 + char
mais beaucoup plus rapide. C'est bien parce que c'est tellement rapide, et 31 est un petit nombre premier. Gagner y gagner.
(hash * 31) + char
est identique à la sortie produite par le code basé sur le décalage ((hash<<5)-hash)+char
, même pour les chaînes très longues (je l'ai testé avec des chaînes contenant plus d'un million de caractères), donc ce n'est pas "inutilisable" en termes de précision. La complexité est O (n) pour les versions basées sur les nombres et sur les équipes, donc elle n'est pas "inutilisable" en termes de complexité.
n
, quelle est la plus grande n
pour laquelle je ne peux pas avoir de collision?
var hashCode = function hashCode (str) {etc...}
? Et puis utiliser comme hashCode("mystring")
?
ÉDITER
sur la base de mes tests jsperf, la réponse acceptée est en fait plus rapide: http://jsperf.com/hashcodelordvlad
ORIGINAL
si quelqu'un est intéressé, voici une version améliorée (plus rapide), qui échouera sur les navigateurs plus anciens qui n'ont pas la reduce
fonction tableau.
hashCode = function(s){
return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
version de fonction flèche à une ligne:
hashCode = s => s.split('').reduce((a,b)=>{a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)
Remarque: même avec le meilleur hachage 32 bits, des collisions se produiront tôt ou tard.
La probabilité de collision de hachage peut être calculée comme , approximée par ( voir ici ). Cela peut être plus élevé que ne le suggère l'intuition: en
supposant un hachage 32 bits et k = 10 000 éléments, une collision se produira avec une probabilité de 1,2%. Pour 77 163 échantillons, la probabilité devient 50%! ( calculatrice ).
Je suggère une solution de contournement en bas.
En réponse à cette question
Quel algorithme de hachage est le meilleur pour l'unicité et la vitesse? , Ian Boyd a publié une bonne analyse approfondie . En bref (comme je l'interprète), il arrive à la conclusion que Murmur est le meilleur, suivi de FNV-1a.
L'algorithme String.hashCode () de Java proposé par esmiralha semble être une variante de DJB2.
Quelques benchmarks avec de grandes chaînes d'entrée ici: http://jsperf.com/32-bit-hash
Lorsque des chaînes d'entrée courtes sont hachées, les performances de murmure chutent, par rapport à DJ2B et FNV-1a: http://jsperf.com/32- bit-hash / 3
Donc, en général, je recommanderais murmur3.
Voir ici pour une implémentation JavaScript:
https://github.com/garycourt/murmurhash-js
Si les chaînes d'entrée sont courtes et que les performances sont plus importantes que la qualité de distribution, utilisez DJB2 (comme proposé par la réponse acceptée par esmiralha).
Si la qualité et la petite taille du code sont plus importantes que la vitesse, j'utilise cette implémentation de FNV-1a (basée sur ce code ).
/**
* Calculate a 32 bit FNV-1a hash
* Found here: https://gist.github.com/vaiorabbit/5657561
* Ref.: http://isthe.com/chongo/tech/comp/fnv/
*
* @param {string} str the input value
* @param {boolean} [asString=false] set to true to return the hash value as
* 8-digit hex string instead of an integer
* @param {integer} [seed] optionally pass the hash of the previous chunk
* @returns {integer | string}
*/
function hashFnv32a(str, asString, seed) {
/*jshint bitwise:false */
var i, l,
hval = (seed === undefined) ? 0x811c9dc5 : seed;
for (i = 0, l = str.length; i < l; i++) {
hval ^= str.charCodeAt(i);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
if( asString ){
// Convert to 8 digit hex string
return ("0000000" + (hval >>> 0).toString(16)).substr(-8);
}
return hval >>> 0;
}
Améliorez la probabilité de collision
Comme expliqué ici , nous pouvons étendre la taille des bits de hachage en utilisant cette astuce:
function hash64(str) {
var h1 = hash32(str); // returns 32 bit (as 8 byte hex string)
return h1 + hash32(h1 + str); // 64 bit (as 16 byte hex string)
}
Utilisez-le avec soin et n'en attendez pas trop.
("0000000" + (hval >>> 0).toString(16)).substr(-8);
? N'est-ce pas la même chose que (hval >>> 0).toString(16)
?
hval
, il (hval >>> 0).toString(16)
peut contenir moins de 8 caractères, vous devez donc le remplir avec des zéros. J'étais juste confus, car (hval >>> 0).toString(16)
il en résultait toujours pour moi une chaîne de 8 caractères exactement.
Math.imul
fonction ES6 . Cela en fait à lui seul des références de référence, et finalement un meilleur choix que DJB2 à long terme.
Basé sur la réponse acceptée dans ES6. Plus petit, maintenable et fonctionne dans les navigateurs modernes.
function hashCode(str) {
return str.split('').reduce((prevHash, currVal) =>
(((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);
}
// Test
console.log("hashCode(\"Hello!\"): ", hashCode('Hello!'));
EDIT (2019-11-04) :
version de fonction flèche à une ligne:
const hashCode = s => s.split('').reduce((a,b) => (((a << 5) - a) + b.charCodeAt(0))|0, 0)
// test
console.log(hashCode('Hello!'))
str += ""
avant le hachage pour éviter les exceptions str.split is not a function
levées lorsque des non-chaînes ont été passées en tant que paramètres
hash |= 0
pour convertir en un entier 32 bits. Cette implémentation ne fonctionne pas. Est-ce un bug?
Près de la moitié des réponses sont des implémentations de Java
String.hashCode
, qui ne sont ni de haute qualité ni super rapides. Ce n'est rien de trop spécial, il multiplie juste par 31 pour chaque personnage. Il peut être implémenté simplement et efficacement sur une seule ligne, et est beaucoup plus rapide avecMath.imul
:
hashCode=s=>{for(var i=0,h;i<s.length;i++)h=Math.imul(31,h)+s.charCodeAt(i)|0;return h}
Avec cela à l'écart, voici quelque chose de mieux - cyrb53 , un hachage 53 bits simple mais de haute qualité. Il est assez rapide, offre une très bonne distribution de hachage et présente des taux de collision nettement inférieurs à ceux de tout hachage 32 bits.
const cyrb53 = function(str, seed = 0) {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ h1>>>16, 2246822507) ^ Math.imul(h2 ^ h2>>>13, 3266489909);
h2 = Math.imul(h2 ^ h2>>>16, 2246822507) ^ Math.imul(h1 ^ h1>>>13, 3266489909);
return 4294967296 * (2097151 & h2) + (h1>>>0);
};
Semblable aux algorithmes MurmurHash / xxHash bien connus, il utilise une combinaison de multiplication et de Xorshift pour générer le hachage, mais pas aussi complètement. En conséquence, c'est plus rapide qu'en JavaScript et beaucoup plus simple à mettre en œuvre.
Il réalise une avalanche (non stricte), ce qui signifie essentiellement que de petits changements dans l'entrée ont de grands changements dans la sortie, ce qui fait que le hachage résultant semble aléatoire:
0xc2ba782c97901 = cyrb53("a")
0xeda5bc254d2bf = cyrb53("b")
0xe64cc3b748385 = cyrb53("revenge")
0xd85148d13f93a = cyrb53("revenue")
Vous pouvez également fournir une valeur de départ pour des flux alternatifs de la même entrée:
0xee5e6598ccd5c = cyrb53("revenue", 1)
0x72e2831253862 = cyrb53("revenue", 2)
0x0de31708e6ab7 = cyrb53("revenue", 3)
Techniquement, il s'agit d'un hachage 64 bits (deux hachages 32 bits non corrélés en parallèle), mais JavaScript est limité à des entiers 53 bits. Si nécessaire, la sortie 64 bits complète peut toujours être utilisée en modifiant la ligne de retour pour une chaîne hexadécimale ou un tableau.
Sachez que la construction de chaînes hexadécimales peut considérablement ralentir le traitement par lots dans des situations critiques pour les performances.
return (h2>>>0).toString(16).padStart(8,0)+(h1>>>0).toString(16).padStart(8,0);
// or
return [h2>>>0, h1>>>0];
Et juste pour le plaisir, voici un hachage 32 bits minimal en 89 caractères avec une qualité supérieure à celle de FNV ou DJB2:
TSH=s=>{for(var i=0,h=9;i<s.length;)h=Math.imul(h^s.charCodeAt(i++),9**9);return h^h>>>9}
ch
initialisé?
'imul'
.
Si cela aide quelqu'un, j'ai combiné les deux premières réponses dans une version plus ancienne, reduce
compatible avec les navigateurs, qui utilise la version rapide si elle est disponible et revient à la solution d'esmiralha si elle ne l'est pas.
/**
* @see http://stackoverflow.com/q/7616461/940217
* @return {number}
*/
String.prototype.hashCode = function(){
if (Array.prototype.reduce){
return this.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
var hash = 0;
if (this.length === 0) return hash;
for (var i = 0; i < this.length; i++) {
var character = this.charCodeAt(i);
hash = ((hash<<5)-hash)+character;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
L'utilisation est comme:
var hash = "some string to be hashed".hashCode();
String.prototype.hashCode = function(){ var hash = 5381; if (this.length === 0) return hash; for (var i = 0; i < this.length; i++) { var character = this.charCodeAt(i); hash = ((hash<<5)+hash)^character; // Convert to 32bit integer } return hash; }
Il s'agit d'une variante raffinée et plus performante:
String.prototype.hashCode = function() {
var hash = 0, i = 0, len = this.length;
while ( i < len ) {
hash = ((hash << 5) - hash + this.charCodeAt(i++)) << 0;
}
return hash;
};
Cela correspond à l'implémentation Java de la norme object.hashCode()
Voici également celui qui ne renvoie que des codes de hachage positifs:
String.prototype.hashcode = function() {
return (this.hashCode() + 2147483647) + 1;
};
Et voici un correspondant pour Java qui ne renvoie que des codes de hachage positifs:
public static long hashcode(Object obj) {
return ((long) obj.hashCode()) + Integer.MAX_VALUE + 1l;
}
Prendre plaisir!
Je suis un peu surpris que personne n'ait encore parlé de la nouvelle API SubtleCrypto .
Pour obtenir un hachage à partir d'une chaîne, vous pouvez utiliser la subtle.digest
méthode:
function getHash(str, algo = "SHA-256") {
let strBuf = new TextEncoder('utf-8').encode(str);
return crypto.subtle.digest(algo, strBuf)
.then(hash => {
window.hash = hash;
// here hash is an arrayBuffer,
// so we'll connvert it to its hex version
let result = '';
const view = new DataView(hash);
for (let i = 0; i < hash.byteLength; i += 4) {
result += ('00000000' + view.getUint32(i).toString(16)).slice(-8);
}
return result;
});
}
getHash('hello world')
.then(hash => {
console.log(hash);
});
var promise = crypto.subtle.digest({name: "SHA-256"}, Uint8Array.from(data)); promise.then(function(result){ console.log(Array.prototype.map.call(new Uint8Array(result), x => x.toString(16).padStart(2, '0')).join('')); });
crypto
n'est pas exactement performante.
Grâce à l'exemple de mar10, j'ai trouvé un moyen d'obtenir les mêmes résultats en C # ET Javascript pour un FNV-1a. Si des caractères unicode sont présents, la partie supérieure est supprimée pour des raisons de performances. Je ne sais pas pourquoi il serait utile de les conserver lors du hachage, car je ne hache que les chemins d'URL pour l'instant.
Version C #
private static readonly UInt32 FNV_OFFSET_32 = 0x811c9dc5; // 2166136261
private static readonly UInt32 FNV_PRIME_32 = 0x1000193; // 16777619
// Unsigned 32bit integer FNV-1a
public static UInt32 HashFnv32u(this string s)
{
// byte[] arr = Encoding.UTF8.GetBytes(s); // 8 bit expanded unicode array
char[] arr = s.ToCharArray(); // 16 bit unicode is native .net
UInt32 hash = FNV_OFFSET_32;
for (var i = 0; i < s.Length; i++)
{
// Strips unicode bits, only the lower 8 bits of the values are used
hash = hash ^ unchecked((byte)(arr[i] & 0xFF));
hash = hash * FNV_PRIME_32;
}
return hash;
}
// Signed hash for storing in SQL Server
public static Int32 HashFnv32s(this string s)
{
return unchecked((int)s.HashFnv32u());
}
Version JavaScript
var utils = utils || {};
utils.FNV_OFFSET_32 = 0x811c9dc5;
utils.hashFnv32a = function (input) {
var hval = utils.FNV_OFFSET_32;
// Strips unicode bits, only the lower 8 bits of the values are used
for (var i = 0; i < input.length; i++) {
hval = hval ^ (input.charCodeAt(i) & 0xFF);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
return hval >>> 0;
}
utils.toHex = function (val) {
return ("0000000" + (val >>> 0).toString(16)).substr(-8);
}
Math.imul
peut être utilisé pour l'étape de multiplication, ce qui améliore considérablement les performances . Le seul problème est que cela ne fonctionnera pas dans IE11 sans cale .
Un rapide et concis qui a été adapté à partir d' ici :
String.prototype.hashCode = function() {
var hash = 5381, i = this.length
while(i)
hash = (hash * 33) ^ this.charCodeAt(--i)
return hash >>> 0;
}
J'avais besoin d'une fonction similaire (mais différente) pour générer un identifiant unique basé sur le nom d'utilisateur et l'heure actuelle. Donc:
window.newId = ->
# create a number based on the username
unless window.userNumber?
window.userNumber = 0
for c,i in window.MyNamespace.userName
char = window.MyNamespace.userName.charCodeAt(i)
window.MyNamespace.userNumber+=char
((window.MyNamespace.userNumber + Math.floor(Math.random() * 1e15) + new Date().getMilliseconds()).toString(36)).toUpperCase()
Produit:
2DVFXJGEKL
6IZPAKFQFL
ORGOENVMG
... etc
modifier juin 2015: pour le nouveau code, j'utilise shortid: https://www.npmjs.com/package/shortid
Ma doublure rapide (très longue) basée sur la Multiply+Xor
méthode FNV :
my_string.split('').map(v=>v.charCodeAt(0)).reduce((a,v)=>a+((a<<7)+(a<<3))^v).toString(16);
Je n'utilise pas de langage côté serveur, je ne peux donc pas le faire de cette façon.
Êtes-vous sûr de ne pas pouvoir procéder de cette façon ?
Avez-vous oublié que vous utilisez Javascript, la langue en constante évolution?
Essayez SubtleCrypto
. Il prend en charge les fonctions de hachage SHA-1, SHA-128, SHA-256 et SHA-512.
async function hash(message/*: string */) {
const text_encoder = new TextEncoder;
const data = text_encoder.encode(message);
const message_digest = await window.crypto.subtle.digest("SHA-512", data);
return message_digest;
} // -> ArrayBuffer
function in_hex(data/*: ArrayBuffer */) {
const octets = new Uint8Array(data);
const hex = [].map.call(octets, octet => octet.toString(16).padStart(2, "0")).join("");
return hex;
} // -> string
(async function demo() {
console.log(in_hex(await hash("Thanks for the magic.")));
})();
Je suis un peu en retard à la fête, mais vous pouvez utiliser ce module: crypto :
const crypto = require('crypto');
const SALT = '$ome$alt';
function generateHash(pass) {
return crypto.createHmac('sha256', SALT)
.update(pass)
.digest('hex');
}
Le résultat de cette fonction est toujours une 64
chaîne de caractères; quelque chose comme ça:"aa54e7563b1964037849528e7ba068eb7767b1fab74a8d80fe300828b996714a"
J'ai combiné les deux solutions (utilisateurs esmiralha et lordvlad) pour obtenir une fonction qui devrait être plus rapide pour les navigateurs prenant en charge la fonction js reduction () et toujours compatible avec les anciens navigateurs:
String.prototype.hashCode = function() {
if (Array.prototype.reduce) {
return this.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
} else {
var hash = 0, i, chr, len;
if (this.length == 0) return hash;
for (i = 0, len = this.length; i < len; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
};
Exemple:
my_string = 'xyz';
my_string.hashCode();
Si vous souhaitez éviter les collisions, vous pouvez utiliser un hachage sécurisé comme SHA-256 . Il existe plusieurs implémentations JavaScript SHA-256.
J'ai écrit des tests pour comparer plusieurs implémentations de hachage, voir https://github.com/brillout/test-javascript-hash-implementations .
Ou accédez à http://brillout.github.io/test-javascript-hash-implementations/ , pour exécuter les tests.
Cela devrait être un hachage un peu plus sécurisé que certaines autres réponses, mais dans une fonction, sans source préchargée
J'ai essentiellement créé une version simplifiée simplifiée de sha1.
Vous prenez les octets de la chaîne et les regroupez par "mots" de 4 à 32 bits.
Ensuite, nous étendons tous les 8 mots à 40 mots (pour un impact plus important sur le résultat).
Cela va à la fonction de hachage (la dernière réduction) où nous faisons quelques calculs avec l'état actuel et l'entrée. Nous obtenons toujours 4 mots.
C'est presque une version à une commande / une ligne utilisant la carte, réduire ... au lieu de boucles, mais c'est toujours assez rapide
String.prototype.hash = function(){
var rot = (word, shift) => word << shift | word >>> (32 - shift);
return unescape(encodeURIComponent(this.valueOf())).split("").map(char =>
char.charCodeAt(0)
).reduce((done, byte, idx, arr) =>
idx % 4 == 0 ? [...done, arr.slice(idx, idx + 4)] : done
, []).reduce((done, group) =>
[...done, group[0] << 24 | group[1] << 16 | group[2] << 8 | group[3]]
, []).reduce((done, word, idx, arr) =>
idx % 8 == 0 ? [...done, arr.slice(idx, idx + 8)] : done
, []).map(group => {
while(group.length < 40)
group.push(rot(group[group.length - 2] ^ group[group.length - 5] ^ group[group.length - 8], 3));
return group;
}).flat().reduce((state, word, idx, arr) => {
var temp = ((state[0] + rot(state[1], 5) + word + idx + state[3]) & 0xffffffff) ^ state[idx % 2 == 0 ? 4 : 5](state[0], state[1], state[2]);
state[0] = rot(state[1] ^ state[2], 11);
state[1] = ~state[2] ^ rot(~state[3], 19);
state[2] = rot(~state[3], 11);
state[3] = temp;
return state;
}, [0xbd173622, 0x96d8975c, 0x3a6d1a23, 0xe5843775,
(w1, w2, w3) => (w1 & rot(w2, 5)) | (~rot(w1, 11) & w3),
(w1, w2, w3) => w1 ^ rot(w2, 5) ^ rot(w3, 11)]
).slice(0, 4).map(p =>
p >>> 0
).map(word =>
("0000000" + word.toString(16)).slice(-8)
).join("");
};
nous convertissons également la sortie en hexadécimal pour obtenir une chaîne au lieu d'un tableau de mots.
L'utilisation est simple. par exemple "a string".hash()
reviendra"88a09e8f9cc6f8c71c4497fbb36f84cd"
J'ai opté pour une simple concaténation des codes de caractères convertis en chaînes hexadécimales. Cela sert un objectif relativement étroit, à savoir avoir juste besoin d'une représentation de hachage d'une chaîne SHORT (par exemple, titres, balises) à échanger avec un côté serveur qui, pour des raisons non pertinentes, ne peut pas facilement implémenter le port Java hashCode accepté. Évidemment aucune application de sécurité ici.
String.prototype.hash = function() {
var self = this, range = Array(this.length);
for(var i = 0; i < this.length; i++) {
range[i] = i;
}
return Array.prototype.map.call(range, function(i) {
return self.charCodeAt(i).toString(16);
}).join('');
}
Cela peut être rendu plus concis et tolérant au navigateur avec Underscore. Exemple:
"Lorem Ipsum".hash()
"4c6f72656d20497073756d"
Je suppose que si vous vouliez hacher des chaînes plus grandes de la même manière, vous pourriez simplement réduire les codes de caractères et hexifier la somme résultante plutôt que de concaténer les caractères individuels ensemble:
String.prototype.hashLarge = function() {
var self = this, range = Array(this.length);
for(var i = 0; i < this.length; i++) {
range[i] = i;
}
return Array.prototype.reduce.call(range, function(sum, i) {
return sum + self.charCodeAt(i);
}, 0).toString(16);
}
'One time, I hired a monkey to take notes for me in class. I would just sit back with my mind completely blank while the monkey scribbled on little pieces of paper. At the end of the week, the teacher said, "Class, I want you to write a paper using your notes." So I wrote a paper that said, "Hello! My name is Bingo! I like to climb on things! Can I have a banana? Eek, eek!" I got an F. When I told my mom about it, she said, "I told you, never trust a monkey!"'.hashLarge()
"9ce7"
Naturellement plus de risques de collision avec cette méthode, bien que vous puissiez jouer avec l'arithmétique dans la réduction, mais vous vouliez diversifier et allonger le hachage.
Version légèrement simplifiée de la réponse de @ esmiralha.
Je ne remplace pas String dans cette version, car cela pourrait entraîner un comportement indésirable.
function hashCode(str) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = ~~(((hash << 5) - hash) + str.charCodeAt(i));
}
return hash;
}
Ajouter cela parce que personne ne l'a encore fait, et cela semble être demandé et implémenté beaucoup avec des hachages, mais c'est toujours très mal fait ...
Cela prend une entrée de chaîne et un nombre maximum que vous souhaitez que le hachage soit égal et produit un nombre unique basé sur l'entrée de chaîne.
Vous pouvez l'utiliser pour produire un index unique dans un tableau d'images (si vous souhaitez renvoyer un avatar spécifique pour un utilisateur, choisi au hasard, mais également choisi en fonction de son nom, il sera donc toujours attribué à quelqu'un avec ce nom ).
Vous pouvez également l'utiliser, bien sûr, pour renvoyer un index dans un tableau de couleurs, comme pour générer des couleurs d'arrière-plan d'avatar uniques en fonction du nom de quelqu'un.
function hashInt (str, max = 1000) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = ((hash << 5) - hash) + str.charCodeAt(i);
hash = hash & hash;
}
return Math.round(max * Math.abs(hash) / 2147483648);
}
Je ne vois aucune raison d'utiliser ce code cryptographique trop compliqué au lieu de solutions prêtes à l'emploi, comme une bibliothèque de hachage d'objets, etc., compter sur le fournisseur est plus productif, fait gagner du temps et réduit les coûts de maintenance.
Utilisez simplement https://github.com/puleos/object-hash
var hash = require('object-hash');
hash({foo: 'bar'}) // => '67b69634f9880a282c14a0f0cb7ba20cf5d677e9'
hash([1, 2, 2.718, 3.14159]) // => '136b9b88375971dff9f1af09d7356e3e04281951'
var crypto = require('crypto');
. Je pense qu'il ajoute ce code de dépendance du fournisseur dans la version minifiée lors d'une build.