57

如何计算特定单元格中文本的 MD5 或 SHA1 哈希值并将其设置为 Google 电子表格中的另一个单元格?

有没有类似=ComputeMD5(A1)or的公式=ComputeSHA1(A1)

或者是否可以为此编写自定义公式?如何?

4

9 回答 9

112

打开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()函数。

于 2012-08-08T15:36:26.067 回答
21

感谢 gabhubert 的代码。

这是该代码的 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;
}
于 2013-10-07T10:18:09.650 回答
6

好的,我知道了,

需要按照 http://code.google.com/googleapps/appsscript/articles/custom_function.html中的说明创建自定义函数

然后按照 http://code.google.com/googleapps/appsscript/service_utilities.html中的说明使用 API

我需要手动输入完整的函数名称,以便在单元格中看到结果。

以下是给出文本的 base 64 编码散列的代码示例

function getBase64EncodedMD5(text)
{ 
  return Utilities.base64Encode( Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, text));
}
于 2011-11-04T14:08:26.467 回答
3

此解决方案与其他解决方案的区别在于:

  1. 它解决了上述解决方案中的一些问题,即偏移输出Utilities.computeDigest(偏移 128 而不是 256)

  2. 它修复了一个问题,该问题导致一些其他解决方案通过在将其传递给之前调用来为不同的输入生成相同的JSON.stringify()哈希inputUtilities.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;
}
于 2018-11-07T17:59:34.797 回答
2

要获取一系列单元格的哈希值,请将其添加到 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)
  }
}

并以这种方式在单元格中使用它:

=RangeGetMD5Hash(A5:X25)

它返回与源一相同维度的范围,值将使用公式从单元格向下和向右传播。

它是通用的单值函数到范围函数的转换方法(ref),并且比每个单元格的单独公式要快得多;在这种形式下,它也适用于单个单元格,因此也许值得以这种方式重写源函数。

于 2014-12-31T08:04:59.720 回答
2

基于@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
}
于 2017-10-25T12:51:10.020 回答
1

如果您想从整行中获取结果,则可以使用@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() 即可获得结果,并避免对函数错误的过多调用。

于 2014-03-25T11:04:22.347 回答
1

我正在寻找一个可以提供更短结果的选项。你怎么看待这件事?它只返回 4 个字符。不幸的是,它使用了 i's 和 o's,这可能会分别与 L's 和 0's 混淆;使用正确的字体和大写字母并不重要。

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();
  }
于 2015-11-12T06:25:24.553 回答
1

我需要在一系列单元格中获取哈希,所以我像这样运行它:

function RangeSHA256(input)
{
    return Array.isArray(input) ?
        input.map(row => row.map(cell => SHA256(cell))) :
        SHA256(input);
}

于 2020-09-22T06:47:37.457 回答