2011-11-03 461 views
19

如何計算特定單元格中文本的MD5或SHA1哈希值並將其設置爲Google Spreadsheet中的另一個單元格?Google電子表格中單元格文本的哈希值

是否有像=ComputeMD5(A1)=ComputeSHA1(A1)的公式?

或者是否有可能爲此編寫自定義公式?怎麼樣?

回答

4

好,我知道,

需要創建自定義功能在 http://code.google.com/googleapps/appsscript/articles/custom_function.html

解釋然後使用這些API作爲 http://code.google.com/googleapps/appsscript/service_utilities.html

解釋我需要handtype完整的功能名稱,以便我可以在單元格中看到結果。

下面是給文字

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

打開Tools > Script Editor然後將以下代碼粘貼基地64編碼哈希代碼示例:

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()函數。

+1

尼斯的答案。您可能需要在函數內部的某處添加Utilities.sleep(100),以防止它在使用自動填充函數時崩潰(否則,您將遇到函數被調用的頻率限制) – leo

+0

我不能似乎得到這個以匹配'md5sum(1)'做的事情;例如cli中的'frew'給出'c241183cbf6766bd86061a60d6c8fe1b'沒有換行符,但函數中有'cfb5d06a43aad502d0f6219143ba0e34'。 –

14

感謝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; 
} 
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(),這樣你可以得到你的結果,並逃避了太多調用函數的錯誤。

+0

預測你看我的答案是這樣做的 – LogicDaemon

1

獲得哈希值的單元格區域,添加此毗鄰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) 

它返回相同的尺寸,來源範圍一個,價值觀將傳播下來,並從單元格公式化。

它是range-func轉換方法的通用單值函數(ref),它比每個單元格的單獨formuleas更快;在這種形式下,它也適用於單細胞,所以也許值得用這種方法重寫源函數。

0

我正在尋找一個可以提供較短結果的選項。你怎麼看待這件事?它只返回4個字符。不幸的是,它使用了i和o,它們可以分別用於L和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(); 
    } 
0

基於@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 
} 
相關問題