Skip to content

Instantly share code, notes, and snippets.

@KEINOS

KEINOS/md5.gs

Last active Oct 21, 2020
Embed
What would you like to do?
GAS(Google Apps Script) user function to get MD5 hash or 4digit shortened hash for Multibyte(UTF-8, 2bytes character) environment.
/**
* ------------------------------------------
* MD5 function for GAS(GoogleAppsScript)
*
* You can get a MD5 hash value and even a 4digit short Hash value of a string.
* ------------------------------------------
* Usage1:
* `=MD5("YourStringToHash")`
* or
* `=MD5( A1 )` with the same string at A1 cell
* result:
* `FCE7453B7462D9DE0C56AFCCFB756193`.
* For your sure-ness you can verify it in your terminal as below.
* `$ md5 -s "YourStringToHash"`
* Usage2:
* `=MD5("YourStringToHash", true)` for short Hash
* result:
* `6MQH`
* Note that it has more conflict probability.
*
* How to install:
* Copy the scipt, pase it at [Tools]-[Script Editor]-[<YourProject>]
* or go https://script.google.com and paste it.
* For more details go:
* https://developers.google.com/apps-script/articles/
* Latest version:
* https://gist.github.com/dotysan/36b99217fdc958465b62f84f66903f07
* Author/Collaborator/Contributor:
* KEINOS @ https://github.com/keinos
* Alex Ivanov @ https://github.com/contributorpw
+ Curtis Doty @ https://github.com/dotysan
* Reference and thanks to:
* https://stackoverflow.com/questions/7994410/hash-of-a-cell-text-in-google-spreadsheet
* https://gist.github.com/KEINOS/78cc23f37e55e848905fc4224483763d#gistcomment-3129967
* https://gist.github.com/dotysan/36b99217fdc958465b62f84f66903f07
* https://developers.google.com/apps-script/reference/utilities/utilities#computedigestalgorithm-value
* https://cloud.google.com/dataprep/docs/html/Logical-Operators_57344671
* ------------------------------------------
*
* @param {(string|Bytes[])} input The value to hash.
* @param {boolean} isShortMode Set true for 4 digit shortend hash, else returns usual MD5 hash.
* @return {string} The hashed input
* @customfunction
*
*/
function MD5( input, isShortMode )
{
var isShortMode = !!isShortMode; // Be sure to be bool
var txtHash = '';
var rawHash = Utilities.computeDigest(
Utilities.DigestAlgorithm.MD5,
input );
if ( ! isShortMode ) {
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 );
};
} else {
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 );
};
};
// change below to "txtHash.toUpperCase()" if needed
return txtHash;
}
@schoraria911

This comment has been minimized.

Copy link

@schoraria911 schoraria911 commented Aug 22, 2019

This is brilliant! Thanks a ton :)

@contributorpw

This comment has been minimized.

Copy link

@contributorpw contributorpw commented Jan 7, 2020

Does var isShortMode = !!isShortMode; work different?

@KEINOS

This comment has been minimized.

Copy link
Owner Author

@KEINOS KEINOS commented Jan 8, 2020

@schoraria911

Thanks! Glad that it helped you!

@contributorpw

work different?

You're right. I guess it works the same. 😳 I think I just wanted to be sure at that time ...

@contributorpw

This comment has been minimized.

Copy link

@contributorpw contributorpw commented Jan 24, 2020

As for me it's a cool function!

@KEINOS

This comment has been minimized.

Copy link
Owner Author

@KEINOS KEINOS commented Jan 26, 2020

@contributorpw

thanks! ☺️

@dotysan

This comment has been minimized.

Copy link

@dotysan dotysan commented Apr 18, 2020

It fails to calculate md5sum for binary data. Since Utilities.computeDigest() already can handle both String and Bytes[] input, don't hard-code String!

@dotysan

This comment has been minimized.

@KEINOS

This comment has been minimized.

Copy link
Owner Author

@KEINOS KEINOS commented Apr 19, 2020

@dotysan

Utilities.computeDigest() already can handle both String and Bytes[] input

Indeed.

It seems that I was too afraid of the other encodings in Japan, such as JIS, SJIS, SJIS-WIN, EUC, ASCII.
But I realized that GAS works with UTF-8. Converting the input string encoding to UTF-8 should be the user side matter. Thanks!

I updated the script a little after all these years.

@rohanchutke

This comment has been minimized.

Copy link

@rohanchutke rohanchutke commented Apr 23, 2020

Can you give me the algorithm to decrypt it back?

@KEINOS

This comment has been minimized.

Copy link
Owner Author

@KEINOS KEINOS commented Apr 24, 2020

@rohanchutke

Can you give me the algorithm to decrypt it back?

I would like to, but unfortunately, I can't ... sorry.

If I could, I might be nominated somehow in the encryption world or be in the breaking world news!!

Note that "hash" is not encryption nor compression. So there's no decryption or decompression as well. You may have a value that collides by calcutlation though.

One of the characteristics of the hash function is that it can not be back-calculated the original value. And another characteristic is that if you provide the same value you get the same result.

This wiki page might help you some.

@dotysan

This comment has been minimized.

Copy link

@dotysan dotysan commented Aug 13, 2020

@KEINOS

This comment has been minimized.

Copy link
Owner Author

@KEINOS KEINOS commented Aug 17, 2020

@Hash7ag asks about license

@dotysan @contributorpw

MIT? Maybe? Is that OK for you two?
Personally, I don't care if it's WTFPL but I would like to respect the contribution.

@harupong

This comment has been minimized.

Copy link

@harupong harupong commented Sep 4, 2020

Does Utilities.computeDigest require another argument Utilities.Charset.UTF_8, in order to properly handle multibyte(UTF-8, 2bytes character) environment?
I couldn't get Japanese multibyte letters processed properly with your function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.