52

I'd like to be able to create unique tokens* for users based on a hashed string. I know I could, for example, use a md5() library but as the purpose is not cryptographic I was wondering if there was anything I could use "out of the box." Are there any one-way hashing functions available in native JavaScript?

*I realize these won't be strictly unique. I'm ok with a small chance of hashing collision.

2
  • 1
    you may like this question - stackoverflow.com/questions/105034/… Commented Feb 24, 2011 at 22:55
  • Yup, like that a lot. I need a one way hash vs. GUIDs. I have a a large string and want to hash it into a smaller string the same way every time. md5 works for that purposes but seems like overkill. Commented Feb 24, 2011 at 23:08

4 Answers 4

24

In 2020, there is a native API:

SubtleCrypto.digest()

https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest

example:

crypto.subtle
  .digest("SHA-256", new TextEncoder().encode("hello"))
  .then(console.log);

hex string conversion:

const digest = async ({ algorithm = "SHA-256", message }) =>
  Array.prototype.map
    .call(
      new Uint8Array(
        await crypto.subtle.digest(algorithm, new TextEncoder().encode(message))
      ),
      (x) => ("0" + x.toString(16)).slice(-2)
    )
    .join("");

digest({message: "hello"}).then(console.log)

Sign up to request clarification or add additional context in comments.

3 Comments

The SubtleCrypto API requires a TLS-enabled website, however. Are there any options that lack this constraint?
Note: all browsers actually supported this by mid 2015 already; except Edge, which didn't have SHA-1 support until Jan 2020 with "New Edge" and the switch to Chromium. Node got support in 2020.
@Drowsy I'm wondering the same thing. This would be very useful to add at least some MITM mitigation for pages that can't use SSL, e.g. embedded systems working on an IP address.
12

JavaScript does not have native hashing, but there are many libraries.

I recommend crypto-js: https://code.google.com/p/crypto-js/

For example, to use SHA1, you simply:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/sha1.js"></script>
<script>
    var hash = CryptoJS.SHA1("Message");
</script>

Comments

6

Nothing is available in native JavaScript. You could use something like Murmurhash. There's a JavaScript implementation here: https://github.com/garycourt/murmurhash-js. I haven't used it though so can't vouch for it.

Update: now there are multiple Murmurhash3 implementations available in JavaScript. However, many of them have problems encoding strings to bytes and can produce different results compared to the reference C++ implementation. You can read an analysis on this here, the murmurhash3js-revisited library implements all three variants of the function and conforms to the reference.

Comments

5

Over the horizon, this may be possible with the currently experimental Web Crypto API

https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API

https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto

Granted, at the time of this writing it is unrealistic to use in a production environment and will likely be a moving target. However, come 5 years who knows?

1 Comment

Personally, I'd really like to explore using this to share code between sites using localStorage (there's a hack allowing to use this cross domain). Crypto signing could protect against a site masking evil code as the saved version of jQuery, for example. CDN does this now, but requires an HTTP request.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.