Хеш текста ячейки в Google Spreadsheet - PullRequest
33 голосов
/ 03 ноября 2011

Как я могу вычислить хэш текста MD5 или SHA1 в определенной ячейке и установить его в другую ячейку в электронной таблице Google?

Есть ли формула типа =ComputeMD5(A1) или =ComputeSHA1(A1)?

Или можно написать собственную формулу для этого? Как?

Ответы [ 8 ]

73 голосов
/ 08 августа 2012

Открыть Tools > Script Editor и вставить следующий код:

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

Сохраните сценарий после этого, а затем используйте функцию MD5() в электронной таблице при обращении к ячейке.

Этот скрипт основан на Utilities.computeDigest () .

20 голосов
/ 07 октября 2013

Спасибо Габхуберту за код.

Это версия этого кода SHA1 (очень простое изменение)

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;
}
5 голосов
/ 04 ноября 2011

Хорошо, понял,

Необходимо создать пользовательскую функцию, как описано в http://code.google.com/googleapps/appsscript/articles/custom_function.html

А затем используйте API, как описано в http://code.google.com/googleapps/appsscript/service_utilities.html

Мне нужно вручную ввести полное имя функции, чтобы я мог видеть результат в ячейке.

Ниже приведен пример кода, который дал зашифрованный хэш 64-й строки текста

function getBase64EncodedMD5(text)
{ 
  return Utilities.base64Encode( Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, text));
}
2 голосов
/ 31 декабря 2014

, чтобы получить хэши для диапазона ячеек, добавьте следующее к функции Габхубера:

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

и используйте его в ячейке следующим образом:

=RangeGetMD5Hash(A5:X25)

Возвращает тот же диапазонПри измерении в качестве исходного значения значения будут распространяться вниз и вправо от ячейки с формулами.

Это универсальный метод преобразования функции одного значения в диапазон ( ref ), и он работает намного быстрее, чемотдельные формулы для каждой клетки;в этом виде он также работает для одной ячейки, поэтому, возможно, стоит переписать функцию источника таким образом.

1 голос
/ 07 ноября 2018

Разница между этим решением и другими:

1) Устранена проблема, с которой некоторые из приведенных выше решений сталкивались со смещением выходных данных Utilities.computeDigest (смещается на 128 вместо 256)

2) Исправлена ​​ошибка, из-за которой некоторые другие решения генерировали одинаковый хэш для разных входных данных, вызывая JSON.stringify() на input перед передачей его на 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;
}
1 голос
/ 25 октября 2017

На основе @gabhubert, но с использованием операций с массивами для получения шестнадцатеричного представления

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
}
1 голос
/ 25 марта 2014

Используя ответ @gabhubert, вы можете сделать это, если хотите получить результаты из целого ряда.Из редактора сценариев.

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
  }  
}

А затем из меню «Выполнить» просто запустите функцию StraightToText (), чтобы вы могли получить свой результат и избежать слишком большого количества обращений к ошибке функции.

0 голосов
/ 12 ноября 2015

Я искал вариант, который бы дал более короткий результат. Что Вы думаете об этом? Он возвращает только 4 символа. К сожалению, он использует «я» и «о», которые можно спутать с «л» и «0» соответственно; с правильным шрифтом и заглавными буквами это не будет иметь большого значения.

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();
  }
...