SHA256算法C++实现

一、SHA256算法介绍
  SHA256算法总体上来说就是对原始数据进行分段加密,并且当前分段的加密结果受到上一分段加密结果的影响,最后一段的加密结果就是最终的结果(和混沌系统有点类似)。
  具体的算法细节见博客《SHA256算法原理详解

二、SHA256算法C++实现
1)sha256.h

/*
 * Copyright (c)
 * Filename:    sha256.h
 * Brief:       SHA256算法实现
 * Depend:      C++11
 *
 * Version:     V1.0.0
 * Date:        2019/11/08-2019/11/13
 * Author:      LucianY
 * Note:        初次版本。
 * 
 * Version:     V2.0.0
 * Date:        2023/01/04
 * Author:      LucianY
 * Note:        1、代码优化:使用单例模式;
 *              2、debug:支持加密空字符串;
 *              3、性能优化。
 * 
 * Attention:   输入信息中有中文时,得到的数字指纹与使用其他工具得到数字指纹可能不相同。原因是不同平台中文的编码方式不同。
 */

#ifndef LY_SHA256_H
#define LY_SHA256_H

#include <cstdint>

#include <string>
#include <vector>

namespace Ly {
   

/**
 * @brief SHA256加密类
*/
class Sha256 {
   
public:
    //! 获取单例
    inline static Sha256 &getInstance()
    {
   
        static Sha256 instance;
        return instance;
    }

    /** 
     * @brief: 使用SHA256算法,加密输入信息(获取数字指纹)
     * @param[in] message: 输入信息
     * @return: 摘要(数字指纹)
    */
    std::vector<uint8_t> encrypt(std::vector<uint8_t> message) const;

    /** 
     * @brief: 获取十六进制表示的信息摘要(数字指纹)
     * @param[in] message: 输入信息
     * @return: 十六进制表示的信息摘要(数字指纹)
    */
    std::string getHexMessageDigest(const std::string &message) const;

protected:
    /// SHA256算法中定义的6种逻辑运算 ///

    inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z) const noexcept
    {
   
        return (x & y) ^ ((~x) & z);
    }

    inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z) const noexcept
    {
   
        return (x & y) ^ (x & z) ^ (y & z);
    }

    inline uint32_t bigSigma0(uint32_t x) const noexcept
    {
   
        return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10);
    }

    inline uint32_t bigSigma1(uint32_t x) const noexcept
    {
   
        return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7);
    }

    inline uint32_t smallSigma0(uint32_t x) const noexcept
    {
   
        return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3);
    }

    inline uint32_t smallSigma1(uint32_t x) const noexcept
    {
   
        return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10);
    }

    /** 
     * @brief: SHA256算法对输入信息的预处理,包括“附加填充比特”和“附加长度值”
            附加填充比特: 在报文末尾进行填充,先补第一个比特为1,然后都补0,直到长度满足对512取模后余数是448。需要注意的是,信息必须进行填充。
            附加长度值: 用一个64位的数据来表示原始消息(填充前的消息)的长度,并将其补到已经进行了填充操作的消息后面。
     * @param[in][out] message: 待处理的信息
    */
    void preprocessing(std::vector<uint8_t> &message) const;

    /** 
     * @brief: 将信息分解成连续的64Byte大小的数据块
     * @param[in] message: 输入信息,长度为64Byte的倍数
     * @return: 输出数据块
    */
    std::vector<std::vector<uint8_t>> breakTextInto64ByteChunks(const std::vector<uint8_t> &message) const;

    /** 
     * @brief: 由64Byte大小的数据块,构造出64个4Byte大小的字。
            构造算法:前16个字直接由数据块分解得到,其余的字由如下迭代公式得到:
            W[t] = smallSigma1(W[t-2]) + W[t-7] + smallSigma0(W[t-15]) + W[t-16]
     * @param[in] chunk: 输入数据块,大小为64Byte
     * @return: 输出字
    */
    std::vector<uint32_t> structureWords(const std::vector<uint8_t> &chunk) const;

    /** 
     * @breif: 基于64个4Byte大小的字,进行64次循环加密
     * @param[in] words: 64个4Byte大小的字
     * @param[in][out] message_digest: 信息摘要
    */
    void transform(const std::vector
您好!SHA-256(Secure Hash Algorithm 256-bit)是一种常用的哈希算法,用于将任意长度的数据转换为固定长度(256位)的哈希值。以下是一个使用C语言实现SHA-256算法的示例代码: ```c #include <stdio.h> #include <stdint.h> #include <string.h> #include <stdlib.h> #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) uint32_t ch(uint32_t x, uint32_t y, uint32_t z) { return (x & y) ^ (~x & z); } uint32_t maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) ^ (x & z) ^ (y & z); } uint32_t ep0(uint32_t x) { return ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22); } uint32_t ep1(uint32_t x) { return ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25); } uint32_t sig0(uint32_t x) { return ROTR(x, 7) ^ ROTR(x, 18) ^ (x >> 3); } uint32_t sig1(uint32_t x) { return ROTR(x, 17) ^ ROTR(x, 19) ^ (x >> 10); } void sha256(uint8_t *message, size_t len, uint8_t *hash) { uint32_t h[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; uint32_t k[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0xfc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x6ca6351, 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 }; size_t new_len = ((((len + 8) / 64) + 1) * 64) - 8; uint8_t *msg = (uint8_t *)malloc(new_len + 64); memcpy(msg, message, len); msg[len] = 128; for (size_t i = len + 1; i < new_len; ++i) { msg[i] = 0; } uint64_t bit_len = len * 8; memcpy(msg + new_len, &bit_len, sizeof(uint64_t)); for (size_t offset = 0; offset < new_len; offset += 64) { uint32_t w[64]; for (size_t i = 0; i < 16; ++i) { w[i] = (msg[offset + i * 4] << 24) | (msg[offset + i * 4 + 1] << 16) | (msg[offset + i * 4 + 2] << 8) | (msg[offset + i * 4 + 3]); } for (size_t i = 16; i < 64; ++i) { w[i] = sig1(w[i - 2]) + w[i - 7] + sig0(w[i - 15]) + w[i - 16]; } uint32_t a = h[0]; uint32_t b = h[1]; uint32_t c = h[2]; uint32_t d = h[3]; uint32_t e = h[4]; uint32_t f = h[5]; uint32_t g = h[6]; uint32_t h_ = h[7]; for (size_t i = 0; i < 64; ++i) { uint32_t t1 = h_ + ep1(e) + ch(e, f, g) + k[i] + w[i]; uint32_t t2 = ep0(a) + maj(a, b, c); h_ = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2; } h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e; h[5] += f; h[6] += g; h[7] += h_; } for (size_t i = 0; i < 8; ++i) { hash[i * 4] = (h[i] >> 24) & 0xFF; hash[i * 4 + 1] = (h[i] >> 16) & 0xFF; hash[i * 4 + 2] = (h[i] >> 8) & 0xFF; hash[i * 4 + 3] = h[i] & 0xFF; } free(msg); } int main() { uint8_t message[] = "Hello, world!"; uint8_t hash[32]; sha256(message, sizeof(message) - 1, hash); printf("SHA-256 Hash: "); for (size_t i = 0; i < 32; ++i) { printf("%02x", hash[i]); } printf("\n"); return 0; } ``` 这段代码实现了SHA-256算法的核心部分,可以将输入的消息(message)转换为对应的SHA-256哈希值。运行示例代码会输出消息 "Hello, world!" 的SHA-256哈希值。请注意,此处的代码仅作为参考,实际应用中建议使用经过充分测试和验证的库或工具来计算SHA-256哈希。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值