Fancy DSA Fancy DSA
数据结构
算法
LeetCode
  • 关于
  • 导航 (opens new window)
  • 分类
  • 标签
  • 归档
设计模式 (opens new window)
博客 (opens new window)
GitHub (opens new window)

Jonsam NG

想的更多,也要想的更远
数据结构
算法
LeetCode
  • 关于
  • 导航 (opens new window)
  • 分类
  • 标签
  • 归档
设计模式 (opens new window)
博客 (opens new window)
GitHub (opens new window)
  • 开始上手
  • Plan 计划
  • Roadmap 路线
  • 算法简介
  • Sort 排序

  • Search 搜索

  • Recursive 递归

  • Graph 图

  • Tree 树

  • Math 数学

  • Hash 哈希

    • SHA1 [安全散列算法1]
    • SHA256 [SHA256算法]
      • 介绍
      • 演示
      • 实现
      • 参考
  • String 字符串

  • BitManipulation 位操纵

  • Backtracking 回溯

  • DynamicProgramming 动态规划

  • Cache 缓存

  • Array 数组

  • Ciphers 密码学

  • Conversions 转换

  • ProjectEuler 欧拉计划

  • 其他

  • 算法
  • Hash 哈希
jonsam
2022-05-01
目录

SHA256 [SHA256算法]

# 介绍

SHA-2,名称来自于安全散列演算法 2(英语:Secure Hash Algorithm 2)的缩写,一种密码杂凑函数演算法标准。属于 SHA 演算法之一,是 SHA-1 的后继者。其下又可再分为六个不同的演算法标准,包括了:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。

# 演示

  • SHA-256 加密算法讲解及代码实现:
  • SHA-256 加密算法讲解及代码实现:
  • 256 位加密有多安全?

可视化:

  • Sha256 Algorithm Explained (opens new window)

# 实现

# JavaScript

//= ===============================================================
// SHA256.js
//
// Module that replicates the SHA-256 Cryptographic Hash
// function in Javascript.
//= ===============================================================

// main variables
const CHAR_SIZE = 8

const K = [
  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
]

/**
 * Adds padding to binary/hex string representation
 *
 * @param {string} str - string representation (binary/hex)
 * @param {int} bits - total number of bits wanted
 * @return {string} - string representation padding with empty (0) bits
 *
 * @example
 *      pad("10011", 8); // "00010011"
 */
function pad (str, bits) {
  let res = str
  while (res.length % bits !== 0) {
    res = '0' + res
  }
  return res
}

/**
 * Separates string into chunks of the same size
 *
 * @param {string} str - string to separate into chunks
 * @param {int} size - number of characters wanted in each chunk
 * @return {array} - array of original string split into chunks
 *
 * @example
 *      chunkify("this is a test", 2)
 */
function chunkify (str, size) {
  const chunks = []
  for (let i = 0; i < str.length; i += size) {
    chunks.push(str.slice(i, i + size))
  }
  return chunks
}

/**
 * Rotates string representation of bits to th left
 *
 * @param {string} bits - string representation of bits
 * @param {int} turns - number of rotations to make
 * @return {string} - string representation of bits after rotation
 *
 * @example
 *      rotateLeft("1011", 3); // "1101"
 */
function rotateRight (bits, turns) {
  return bits.substr(bits.length - turns) + bits.substr(0, bits.length - turns)
}

/**
 * Pre-processes message to feed the algorithm loop
 *
 * @param {string} message - message to pre-process
 * @return {string} - processed message
 */
function preProcess (message) {
  // convert message to binary representation padded to
  // 8 bits, and add 1
  let m = message.split('')
    .map(e => e.charCodeAt(0))
    .map(e => e.toString(2))
    .map(e => pad(e, 8))
    .join('') + '1'

  // extend message by adding empty bits (0)
  while (m.length % 512 !== 448) {
    m += '0'
  }

  // length of message in binary, padded, and extended
  // to a 64 bit representation
  let ml = (message.length * CHAR_SIZE).toString(2)
  ml = pad(ml, 8)
  ml = '0'.repeat(64 - ml.length) + ml

  return m + ml
}

/**
 * Hashes message using SHA-256 Cryptographic Hash Function
 *
 * @param {string} message - message to hash
 * @return {string} - message digest (hash value)
 */
function SHA256 (message) {
  // initial hash variables
  let H0 = 0x6a09e667
  let H1 = 0xbb67ae85
  let H2 = 0x3c6ef372
  let H3 = 0xa54ff53a
  let H4 = 0x510e527f
  let H5 = 0x9b05688c
  let H6 = 0x1f83d9ab
  let H7 = 0x5be0cd19

  // pre-process message and split into 512 bit chunks
  const bits = preProcess(message)
  const chunks = chunkify(bits, 512)

  chunks.forEach(function (chunk, i) {
    // break each chunk into 16 32-bit words
    const words = chunkify(chunk, 32)

    // extend 16 32-bit words to 80 32-bit words
    for (let i = 16; i < 64; i++) {
      const W1 = words[i - 15]
      const W2 = words[i - 2]
      const R1 = rotateRight(W1, 7)
      const R2 = rotateRight(W1, 18)
      const R3 = rotateRight(W2, 17)
      const R4 = rotateRight(W2, 19)
      const S0 = parseInt(R1, 2) ^ parseInt(R2, 2) ^ (parseInt(W1, 2) >>> 3)
      const S1 = parseInt(R3, 2) ^ parseInt(R4, 2) ^ (parseInt(W2, 2) >>> 10)
      const val = parseInt(words[i - 16], 2) + S0 + parseInt(words[i - 7], 2) + S1
      words[i] = pad((val >>> 0).toString(2), 32)
    }

    // initialize variables for this chunk
    let [a, b, c, d, e, f, g, h] = [H0, H1, H2, H3, H4, H5, H6, H7]

    for (let i = 0; i < 64; i++) {
      const S1 = [6, 11, 25]
        .map(turns => rotateRight(pad(e.toString(2), 32), turns))
        .map(bitstring => parseInt(bitstring, 2))
        .reduce((acc, curr) => acc ^ curr, 0) >>> 0
      const CH = ((e & f) ^ (~e & g)) >>> 0
      const temp1 = (h + S1 + CH + K[i] + parseInt(words[i], 2)) >>> 0
      const S0 = [2, 13, 22]
        .map(turns => rotateRight(pad(a.toString(2), 32), turns))
        .map(bitstring => parseInt(bitstring, 2))
        .reduce((acc, curr) => acc ^ curr, 0) >>> 0
      const maj = ((a & b) ^ (a & c) ^ (b & c)) >>> 0
      const temp2 = (S0 + maj) >>> 0

      h = g
      g = f
      f = e
      e = (d + temp1) >>> 0
      d = c
      c = b
      b = a
      a = (temp1 + temp2) >>> 0
    }

    // add values for this chunk to main hash variables (unsigned)
    H0 = (H0 + a) >>> 0
    H1 = (H1 + b) >>> 0
    H2 = (H2 + c) >>> 0
    H3 = (H3 + d) >>> 0
    H4 = (H4 + e) >>> 0
    H5 = (H5 + f) >>> 0
    H6 = (H6 + g) >>> 0
    H7 = (H7 + h) >>> 0
  })

  // combine hash values of main hash variables and return
  const HH = [H0, H1, H2, H3, H4, H5, H6, H7]
    .map(e => e.toString(16))
    .map(e => pad(e, 8))
    .join('')

  return HH
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

# 参考

  • SHA-2 - Wikiwand (opens new window)
  • 一文读懂 SHA256 算法原理及其实现 - 知乎 (opens new window)
编辑 (opens new window)
上次更新: 2022/10/25, 20:46:09
SHA1 [安全散列算法1]
AlphaNumericPalindrome [回文串]

← SHA1 [安全散列算法1] AlphaNumericPalindrome [回文串]→

最近更新
01
0-20题解
10-31
02
本章导读
10-31
03
算法与转换:Part1
10-28
更多文章>
Theme by Vdoing | Copyright © 2022-2022 Fancy DSA | Made by Jonsam by ❤
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式