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
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值