web-dev-qa-db-fra.com

Hachage d'un texte de cellule dans Google Spreadsheet

Comment puis-je calculer un hachage MD5 ou SHA1 de texte dans une cellule spécifique et le définir sur une autre cellule de Google Spreadsheet?

Existe-t-il une formule telle que =ComputeMD5(A1) ou =ComputeSHA1(A1)?

Ou est-il possible d'écrire une formule personnalisée pour cela? Comment?

31
HDB

Ouvrez Tools > Script Editor puis collez le code suivant:

function MD5 (input) {
  var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, input);
  var txtHash = '';
  for (i = 0; i < rawHash.length; i++) {
    var hashVal = rawHash[i];
    if (hashVal < 0) {
      hashVal += 256;
    }
    if (hashVal.toString(16).length == 1) {
      txtHash += '0';
    }
    txtHash += hashVal.toString(16);
  }
  return txtHash;
}

Enregistrez le script après cela, puis utilisez la fonction MD5() dans votre feuille de calcul pour référencer une cellule.

Ce script est basé sur Utilities.computeDigest () function.

67
gabhubert

Merci à gabhubert pour le code.

Ceci est la version SHA1 de ce code (changement très simple)

function GetSHA1(input) {
  var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_1, input);
  var txtHash = '';
  for (j = 0; j <rawHash.length; j++) {
    var hashVal = rawHash[j];
    if (hashVal < 0)
      hashVal += 256; 
    if (hashVal.toString(16).length == 1)
     txtHash += "0";
    txtHash += hashVal.toString(16);
    }
  return txtHash;
}
19
Sean Thompson

Ok, j'ai compris,

Il est nécessaire de créer une fonction personnalisée comme expliqué dans http://code.google.com/googleapps/appsscript/articles/custom_function.html

Et puis utilisez les apis comme expliqué dans http://code.google.com/googleapps/appsscript/service_utilities.html

Je dois saisir manuellement le nom complet de la fonction pour pouvoir voir le résultat dans la cellule.

Voici l'exemple de code donnant un hachage codé en base 64 du texte.

function getBase64EncodedMD5(text)
{ 
  return Utilities.base64Encode( Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, text));
}
5
HDB

pour obtenir des hachages pour une plage de cellules, ajoutez ceci à côté de la fonction de gabhubert:

function RangeGetMD5Hash(input) {
  if (input.map) {            // Test whether input is an array.
    return input.map(GetMD5Hash); // Recurse over array if so.
  } else {
    return GetMD5Hash(input)
  }
}

et l'utiliser dans la cellule de cette façon:

=RangeGetMD5Hash(A5:X25)

Il renvoie une plage de mêmes dimensions que la source, les valeurs seront réparties vers le bas et à partir de la cellule avec des formules.

Il s'agit d'une méthode universelle de conversion fonction-valeur unique en fonction plage-fonction ( ref ), et sa méthode est plus rapide que celle de formules séparées pour chaque cellule; sous cette forme, cela fonctionne aussi pour une seule cellule, alors peut-être que ça vaut la peine de réécrire la fonction source de cette façon.

2
LogicDaemon

En utilisant @gabhubert answer, vous pouvez le faire si vous voulez obtenir les résultats sur une ligne entière. De l'éditeur de script.

function GetMD5Hash(value) {
  var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, value);
  var txtHash = '';
    for (j = 0; j <rawHash.length; j++) {
   var hashVal = rawHash[j];
    if (hashVal < 0)
      hashVal += 256; 
    if (hashVal.toString(16).length == 1)
      txtHash += "0";
    txtHash += hashVal.toString(16);
  }
    return txtHash;
}

function straightToText() {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  var r = 1;
  var n_rows = 9999;
  var n_cols = 1;
  var column = 1;
  var sheet = ss[0].getRange(r, column, n_rows, ncols).getValues(); // get first sheet, a1:a9999
  var results = [];
  for (var i = 0; i < sheet.length; i++) {
    var hashmd5= GetMD5Hash(sheet[i][0]);
    results.Push(hashmd5);
  }
  var dest_col = 3;
  for (var j = 0; j < results.length; j++) {
    var row = j+1;
    ss[0].getRange(row, dest_col).setValue(results[j]);  // write output to c1:c9999 as text
  }  
}

Ensuite, dans le menu Exécuter, exécutez simplement la fonction straightToText () afin d’obtenir votre résultat et d’échapper aux appels à une erreur de fonction.

1
Albert Camps

La différence entre cette solution et les autres est la suivante:

1) Cela corrige un problème que certaines des solutions ci-dessus ont avec la compensation de la sortie de Utilities.computeDigest (elle compense par 128 au lieu de 256)

2) Il corrige un problème qui faisait que certaines solutions produisaient le même hachage pour différentes entrées en appelant JSON.stringify() sur input avant de le transmettre à Utilities.computeDigest().

function MD5(input) {
  var result = "";
  var byteArray = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, JSON.stringify(input));
  for (i=0; i < byteArray.length; i++) {
    result += (byteArray[i] + 128).toString(16) + "-";
  }
  result = result.substring(result, result.length - 1); // remove trailing dash
  return result;
}
0
Peter Berg

Basé sur @gabhubert mais utilisant des opérations de tableau pour obtenir la représentation hexadécimale

function sha(str){
    return Utilities
      .computeDigest(Utilities.DigestAlgorithm.SHA_1, str) // string to digested array of integers
      .map(function(val) {return val<0? val+256 : val}) // correct the offset
      .map(function(val) {return ("00" + val.toString(16)).slice(-2)}) // add padding and enconde
      .join(''); // join in a single string
}
0
dinigo

Je cherchais une option qui fournirait un résultat plus court. Que pensez-vous de ceci? Il ne retourne que 4 caractères. Le malheur est qu’il utilise les i et les o qui peuvent être confondus pour L et les 0 respectivement; avec la bonne police et en majuscules, cela n'aurait pas beaucoup d'importance.

function getShortMD5Hash(input) {
  var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, input);
  var txtHash = '';
    for (j = 0; j < 16; j += 8) { 
    hashVal = (rawHash[j] + rawHash[j+1] + rawHash[j+2] + rawHash[j+3]) ^ (rawHash[j+4] + rawHash[j+5] + rawHash[j+6] + rawHash[j+7])
    if (hashVal < 0)
      hashVal += 1024;
    if (hashVal.toString(36).length == 1)
      txtHash += "0";
    txtHash += hashVal.toString(36);
  }
    return txtHash.toUpperCase();
  }
0
donL