哈希算法SHA-256实现示例
参考:

https://en.wikipedia.org/wiki/SHA-2
https://en.wikipedia.org/wiki/Endianness
https://en.wikipedia.org/wiki/Binary_large_object

SHA-256哈希算法计算流程如下:

Note 1: All variables are 32 bit unsigned integers and addition is calculated modulo 232
Note 2: For each round, there is one round constant k[i] and one entry in the message schedule array w[i], 0 ≤ i ≤ 63
Note 3: The compression function uses 8 working variables, a through h
Note 4: Big-endian convention is used when expressing the constants in this pseudocode,and when parsing message block data from bytes to words, for example,the first word of the input message "abc" after padding is 0x61626380Initialize hash values:
(first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19Initialize array of round constants:
(first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
k[0..63] :=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, 0xc67178f2Pre-processing (Padding):
begin with the original message of length L bits
append a single '1' bit
append K '0' bits, where K is the minimum number >= 0 such that L + 1 + K + 64 is a multiple of 512
append L as a 64-bit big-endian integer, making the total post-processed length a multiple of 512 bitsProcess the message in successive 512-bit chunks:
break message into 512-bit chunks
for each chunkcreate a 64-entry message schedule array w[0..63] of 32-bit words(The initial values in w[0..63] don't matter, so many implementations zero them here)copy chunk into first 16 words w[0..15] of the message schedule arrayExtend the first 16 words into the remaining 48 words w[16..63] of the message schedule array:for i from 16 to 63s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3)s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift 10)w[i] := w[i-16] + s0 + w[i-7] + s1Initialize working variables to current hash value:a := h0b := h1c := h2d := h3e := h4f := h5g := h6h := h7Compression function main loop:for i from 0 to 63S1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25)ch := (e and f) xor ((not e) and g)temp1 := h + S1 + ch + k[i] + w[i]S0 := (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22)maj := (a and b) xor (a and c) xor (b and c)temp2 := S0 + majh := gg := ff := ee := d + temp1d := cc := bb := aa := temp1 + temp2Add the compressed chunk to the current hash value:h0 := h0 + ah1 := h1 + bh2 := h2 + ch3 := h3 + dh4 := h4 + eh5 := h5 + fh6 := h6 + gh7 := h7 + hProduce the final hash value (big-endian):
digest := hash := h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7

Bitcoin (0.16.0) 代码实现:

// Internal implementation code.
namespace
{/// Internal SHA-256 implementation.namespace sha256{uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }/** One round of SHA-256. */void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k, uint32_t w){uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;uint32_t t2 = Sigma0(a) + Maj(a, b, c);d += t1;h = t1 + t2;}/** Initialize SHA-256 state. */void inline Initialize(uint32_t* s){s[0] = 0x6a09e667ul;s[1] = 0xbb67ae85ul;s[2] = 0x3c6ef372ul;s[3] = 0xa54ff53aul;s[4] = 0x510e527ful;s[5] = 0x9b05688cul;s[6] = 0x1f83d9abul;s[7] = 0x5be0cd19ul;}/** Perform a number of SHA-256 transformations, processing 64-byte chunks. */void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks){while (blocks--) {uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));s[0] += a;s[1] += b;s[2] += c;s[3] += d;s[4] += e;s[5] += f;s[6] += g;s[7] += h;chunk += 64;}}} // namespace sha256typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t);    TransformType Transform = sha256::Transform;} // namespace

上述代码实现哈希算法中常量的初始化,以及块处理。

/** A hasher class for SHA-256. */class CSHA256
{
private:uint32_t s[8];unsigned char buf[64];uint64_t bytes;public:static const size_t OUTPUT_SIZE = 32;CSHA256();CSHA256& Write(const unsigned char* data, size_t len);void Finalize(unsigned char hash[OUTPUT_SIZE]);CSHA256& Reset();
};
// SHA-256CSHA256::CSHA256() : bytes(0)
{sha256::Initialize(s);
}CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
{const unsigned char* end = data + len;size_t bufsize = bytes % 64;if (bufsize && bufsize + len >= 64) {// Fill the buffer, and process it.memcpy(buf + bufsize, data, 64 - bufsize);bytes += 64 - bufsize;data += 64 - bufsize;Transform(s, buf, 1);bufsize = 0;}if (end - data >= 64) {size_t blocks = (end - data) / 64;Transform(s, data, blocks);data += 64 * blocks;bytes += 64 * blocks;}if (end > data) {// Fill the buffer with what remains.memcpy(buf + bufsize, data, end - data);bytes += end - data;}return *this;
}void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
{static const unsigned char pad[64] = {0x80};unsigned char sizedesc[8];WriteBE64(sizedesc, bytes << 3);Write(pad, 1 + ((119 - (bytes % 64)) % 64));Write(sizedesc, 8);WriteBE32(hash, s[0]);WriteBE32(hash + 4, s[1]);WriteBE32(hash + 8, s[2]);WriteBE32(hash + 12, s[3]);WriteBE32(hash + 16, s[4]);WriteBE32(hash + 20, s[5]);WriteBE32(hash + 24, s[6]);WriteBE32(hash + 28, s[7]);
}CSHA256& CSHA256::Reset()
{bytes = 0;sha256::Initialize(s);return *this;
}

SHA-256封装类,实现数据的长度处理,以及哈希结果值得输出。
其中,用到的一些通用函数,用来处理大端模式与小端模式的转换:

// 以字节为单位,交换64位数据的高低位
inline uint64_t bswap_64(uint64_t x)
{return (((x & 0xff00000000000000ull) >> 56)| ((x & 0x00ff000000000000ull) >> 40)| ((x & 0x0000ff0000000000ull) >> 24)| ((x & 0x000000ff00000000ull) >> 8)| ((x & 0x00000000ff000000ull) << 8)| ((x & 0x0000000000ff0000ull) << 24)| ((x & 0x000000000000ff00ull) << 40)| ((x & 0x00000000000000ffull) << 56));
}
// 以字节为单位,交换32位数据的高低位
inline uint32_t bswap_32(uint32_t x)
{return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >>  8) |((x & 0x0000ff00U) <<  8) | ((x & 0x000000ffU) << 24));
}
// 见bswap_32,大端模式转主机字节(小端模式)
inline uint32_t be32toh(uint32_t big_endian_32bits)
{return bswap_32(big_endian_32bits);
}
// 见bswap_32,主机字节序转大端模式
inline uint32_t htobe32(uint32_t host_32bits)
{return bswap_32(host_32bits);
}
// 见bswap_64,主机字节序转大端模式
inline uint64_t htobe64(uint64_t host_64bits)
{return bswap_64(host_64bits);
}
// 小端模式转主机字节序(无变化)
inline uint64_t le64toh(uint64_t little_endian_64bits)
{return little_endian_64bits;
}
// 从制定内存中读取32位数据,并将其转换为大端模式
uint32_t static inline ReadBE32(const unsigned char* ptr)
{uint32_t x;memcpy((char*)&x, ptr, 4);return be32toh(x);
}
// 将32位数据转换为大端模式,并写入到制定内存
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
{uint32_t v = htobe32(x);memcpy(ptr, (char*)&v, 4);
}
// 将64位数据转换为大端模式,并写入到制定内存
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
{uint64_t v = htobe64(x);memcpy(ptr, (char*)&v, 8);
}
// 从制定那个内存中读取64位数据,并将其转换为主机字节序
uint64_t static inline ReadLE64(const unsigned char* ptr)
{uint64_t x;memcpy((char*)&x, ptr, 8);return le64toh(x);
}

代码中使用的数据类型uint256实现代码如下:

/** Template base class for fixed-sized opaque blobs. */
template<unsigned int BITS>
class base_blob
{
protected:static constexpr int WIDTH = BITS / 8;uint8_t data[WIDTH];
public:base_blob(){memset(data, 0, sizeof(data));}explicit base_blob(const std::vector<unsigned char>& vch);bool IsNull() const{for (int i = 0; i < WIDTH; i++)if (data[i] != 0)return false;return true;}void SetNull(){memset(data, 0, sizeof(data));}inline int Compare(const base_blob& other) const { return memcmp(data, other.data, sizeof(data)); }friend inline bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; }friend inline bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; }friend inline bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; }std::string GetHex() const;void SetHex(const char* psz);void SetHex(const std::string& str);std::string ToString() const;unsigned char* begin(){return &data[0];}unsigned char* end(){return &data[WIDTH];}const unsigned char* begin() const{return &data[0];}const unsigned char* end() const{return &data[WIDTH];}unsigned int size() const{return sizeof(data);}uint64_t GetUint64(int pos) const{const uint8_t* ptr = data + pos * 8;return ((uint64_t)ptr[0]) | \((uint64_t)ptr[1]) << 8 | \((uint64_t)ptr[2]) << 16 | \((uint64_t)ptr[3]) << 24 | \((uint64_t)ptr[4]) << 32 | \((uint64_t)ptr[5]) << 40 | \((uint64_t)ptr[6]) << 48 | \((uint64_t)ptr[7]) << 56;}template<typename Stream>void Serialize(Stream& s) const{s.write((char*)data, sizeof(data));}template<typename Stream>void Unserialize(Stream& s){s.read((char*)data, sizeof(data));}
};
/** 256-bit opaque blob.* @note This type is called uint256 for historical reasons only. It is an* opaque blob of 256 bits and has no integer operations. Use arith_uint256 if* those are required.*/
class uint256 : public base_blob<256> {
public:uint256() {}explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {}/** A cheap hash function that just returns 64 bits from the result, it can be* used when the contents are considered uniformly random. It is not appropriate* when the value can easily be influenced from outside as e.g. a network adversary could* provide values to trigger worst-case behavior.*/uint64_t GetCheapHash() const{return ReadLE64(data);}
};

计算对象的SHA-256哈希值模板实现:

/** Compute the 256-bit hash of an object. */
template<typename T1>
inline uint256 Hash(const T1 pbegin, const T1 pend)
{static const unsigned char pblank[1] = {};uint256 result;CSHA256().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0])).Finalize((unsigned char*)&result);return result;
}

测试源码:

https://github.com/babylco0/bitcoin_code_examples/blob/master/testsha256.cpp

哈希算法SHA-256实现示例相关推荐

  1. sha算法 哈希算法_SHA1哈希算法教程及其用法示例

    sha算法 哈希算法 SHA1 is a hash algorithm that is created by the National Security Agency (NSA). SHA1 hash ...

  2. HashAlgorithm哈希算法信息

    HashAlgorithm 表示所有加密哈希算法实现均必须从中派生的基类 继承层次结构 System.Object   System.Security.Cryptography.HashAlgorit ...

  3. SHA 256算法是什么?哈希算法有哪些特点,主要应用在哪里?

    无论数字证书品牌.价格和类型如何,所有SSL证书的通用规范是采用SHA 256算法,您可以在证书详细信息或产品信息中列出的功能中看到.对于非技术人员来说,SHA 256 算法通常是个谜,但是锐成信息将 ...

  4. 【必备算法】哈希算法:七种应用及场景示例

    在文章开头先看看哈希算法到底什么? 定义:将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法.通过原始数据映射之后得到的二进制值串就是哈希值 需要满足的四点要求: 从哈希值不 ...

  5. 用SHA哈希算法加密密码文件

    在Linux的发行版中,用户的登录密码通常是用MD5算法散列后存储于/etc/shadows文件中的.这种方法的安全性因MD5容易碰撞的特性而相对较弱,虽然这并不意味着MD5对于密码散列算法不可靠.但 ...

  6. 如何生成安全的密码 Hash:MD5, SHA, PBKDF2, BCrypt 示例

    文章推荐 精选java等全套学习资源 精选java电子图书资源 精选大数据学习资源 java项目练习精选 . 一.前言 密码 Hash 值的产生是将用户所提供的密码通过使用一定的算法计算后得到的加密字 ...

  7. java 哈希算法_选择Java密码算法第1部分-哈希

    java 哈希算法 抽象 这是涵盖Java加密算法的三部分博客系列文章的第1部分. 该系列涵盖如何实现以下功能: 使用SHA–512散列 使用AES–256的单密钥对称加密 使用RSA–4096的公钥 ...

  8. 【数据结构与算法】哈希算法

    一.什么是哈希算法? 1.定义 将任意长度的二进制值串映射成固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制值串就是哈希值. 2.如何设计一个优秀的哈希算法? ①单 ...

  9. PHP实现sha-256哈希算法

    哈希 又称作 "散列",它接收任何一组任意长度的输入信息,通过 哈希 算法变换成固定长度的数据指纹,该指纹就是 哈希值.总体而言,哈希 可理解为一种消息摘要. 在 PHP 中有这个 ...

最新文章

  1. hash是线程安全的吗?怎么解决?_这次进程、线程、多线程和线程安全问题,一次性帮你全解决了...
  2. “编程能力差,90%的人会输在这点上!”谷歌开发:其实都是在瞎努力
  3. 《网站设计 开发 维护 推广 从入门到精通》——2.3 页面设计创意思维
  4. 非常完整的coco screator socketio
  5. C# WPF MVVM开发框架Caliburn.Micro View / View Model 命名⑨
  6. 拆卸invokedynamic
  7. 向量外积_解析几何 -向量
  8. 2021湖北高考成绩查询热线,湖北招生考试网:2021年湖北高考成绩查询入口、查分系统...
  9. 基于JAVA+SpringMVC+Mybatis+MYSQL的图书管理系统
  10. FAR,NEAR区别
  11. CentOS 7 安装 JAVA环境(JDK 1.8)
  12. C# ToString()日期格式
  13. win10分屏任务快捷键
  14. MFC---List Control的用法总结
  15. 【ARUN】FastAPIVue 拥有无敌颜值且易用的全栈测试平台 第三弹——测试追踪
  16. 哪些人会看作业指导书?作业指导书怎样才能发挥作用?
  17. LDU 2022年2021级测试赛-1
  18. UCOS-II学习记录
  19. 连接不上服务器怎么办?
  20. xftp和xshell有什么区别

热门文章

  1. 项目经理面试经验宝典
  2. BNB Chain testnet faucet
  3. Java初始化list的8种方式
  4. 【空气质量数据分析专题八】污染物浓度日变化分析
  5. IDL将ENVI中打开的文件转换为其他格式
  6. 5G学习(五):BWP和coreset的那点事儿
  7. 生成tli tlh 文件
  8. 我眼中的信用评分模型
  9. mysql 死锁监控_mysql 死锁
  10. 【STM32F407学习笔记】GPIO(一)