JavaScript 中的 SHA-256 实现

Mehvish Ashiq 2023年1月30日 2022年5月10日
  1. 什么是 JavaScript 中的哈希
  2. 什么是 JavaScript 中的 SHA-256 算法
  3. JavaScript 中的 SHA-256 实现
  4. 在 JavaScript 中使用加密库实现 SHA-256
  5. 在 JavaScript 中使用 node-forge 模块实现 SHA-256
JavaScript 中的 SHA-256 实现

可以生成各种散列,例如 MD5SHA-1SHA-2SHA-256 等。本文重点介绍 JavaScript 中的 SHA-256 实现。

在此之前,最好对散列和 SHA-256 算法有一个基本的了解。开始吧!

什么是 JavaScript 中的哈希

散列是一个将指定的字符串或键转换为无法转换回其真实形式的其他值的过程。哈希函数转换对给定输入(字符串)执行一些数学运算的纯文本。

散列函数产生的输出称为摘要散列值

javascript 中的 sha-256 实现 - 什么是散列

什么是 JavaScript 中的 SHA-256 算法

SHA 代表 Secure Hash Algorithm,它来自 SHA-2 算法家族。SHA-256 中的 256 是什么意思?

这意味着无论纯文本的大小如何,最终的哈希值都将始终为 256 位。SHA-256 也类似于其他 SHA 算法。

让我们开始用 JavaScript 实现 SHA-256

JavaScript 中的 SHA-256 实现

我们将学习在 JavaScript 中实现 SHA-256 的不同方法,你可以根据项目需要使用这些方法。但在此之前,让我们了解如何使用 String 的函数生成哈希。

下面给出示例代码以供练习。

// conversts to 32bit integer
function stringToHashConversion(string) {
 var hashVal = 0;
 if (string.length == 0) return hashVal;
 for (i = 0; i < string.length; i++) {
 char = string.charCodeAt(i);
 hashVal = ((hashVal << 5) - hashVal) + char;
 hashVal = hashVal & hashVal;
    }
 return hashVal;
  }
var input_str = "I am converting string to hash.";
console.log("Input String: "+input_str);
console.log("Hash Value: " + stringToHashConversion(input_str));

输出:

"Input String: I am converting string to hash."
"Hash Value: 625005622"

函数 stringToHashConversion() 为空字符串返回零 (0)。它迭代直到 string.length-1 获得每个字符的 charCode 并通过向左移动 5 位来计算散列。

最终的哈希值是一个 32 位整数。

现在,要关注的重点是 5 位左移。为什么是 5,而不是 6 或 4?这是因为 (hashVal << 5)(hashVal * 32) 相同。

这样,((hashVal << 5) - hashVal) 等价于 (hashVal * 31)。如果我们将 ((hashVal << 5) - hashVal) 替换为 (hashVal * 31),我们会得到相同的哈希值。

你还在为 31 这个数字而困惑吗?

选择 31 是因为它是奇数素数之一。想象一下,如果这是一个偶数并且乘法溢出,所有细节都会消失,因为乘以 2 与移位相同。

那为什么不使用 (hashVal * 31)?这是因为,(hashVal << 5) - hashVal(hashVal * 31) 快。

我们还可以通过使用 ES6 Math.imul 来使用更快的版本,它有助于计算指定两个值的 32 位整数乘法(参见以下代码)。

| 0 优化 hash 以获得更好的速度,并在以下解决方案中将其强制为 32 位数字。

JavaScript 代码:

function stringToHashConversion(string) {
 for(var i = 0, hash = 0; i < string.length; i++)
 hash = Math.imul(31, hash) + string.charCodeAt(i) | 0;
 return hash;
}
var input_str = "I am converting string to hash.";
console.log("Input String: "+input_str);
console.log("Hash Value: " + stringToHashConversion(input_str));

输出:

"Input String: I am converting string to hash."
"Hash Value: 625005622"

在 JavaScript 中使用加密库实现 SHA-256

让我们使用 Crypto 库来实现 SHA-256。使用 require() 方法导入 crypto 模块。

getHashes() 返回所有支持的算法名称。我们使用 createHash() 创建 Hash 对象,它接受两个参数,算法的名称和选项。

第二个参数是可选的。此外,我们使用此 Hash 对象使用指定的算法生成散列摘要。

update() 方法更新数据,digest() 告诉使用的编码。digest 是哈希函数产生的结果,这个结果只有十六进制值。

你可以在这里读更多关于它的内容]。你必须有 Node.js 才能使用 Crypto 库。

JavaScript 代码:

const crypto = require('crypto'),
hash = crypto.getHashes();
var input_str = "I am converting string to hash.";

hashPwd = crypto.createHash('sha256')
    .update(input_str)
    .digest('hex');

console.log("Input String: "+input_str);
console.log("Hash Value: " + hashPwd);

输出:

Input String: I am converting string to hash.
Hash Value: ceb443790638fbc0f543ccf80a08085a731c83a6fd1843c3c3ff2e6edd86c58b

在 JavaScript 中使用 node-forge 模块实现 SHA-256

我们可以使用以下命令在 Node.js 中安装 node-forge 模块,然后使用它。

npm install node-forge

Forge 是 TLS(传输层安全)和 JS (JavaScript) 中不同加密工具的本地实现。首先,我们使用 require() 导入模块,然后通过调用 create() 函数创建一个为 SHA-256 初始化的 forge 对象。

update() 更新数据,而 digest() 函数执行散列并返回给定文本的散列值。请参阅以下代码。

var forge = require('node-forge');
var input_str = "I am converting string to hash.";
var md = forge.md.sha256.create();
md.update(input_str);
console.log("Input String: "+ input_str);
console.log("Hash Value: " + md.digest().toHex());

输出:

Input String: I am converting string to hash.
Hash Value: ceb443790638fbc0f543ccf80a08085a731c83a6fd1843c3c3ff2e6edd86c58b
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook