通过bitset库实现sha256

//sha-256
#include <iostream>
#include <bitset>
#include <string>
#include <string.h>

using namespace std;

typedef bitset<8> byte;  //重命名bitset<8>模板类为byte
typedef bitset<64> word;
typedef bitset<32> w32;
typedef bitset<512> block;  //重命名bitset<128>模板类word
typedef bitset<5120> messagebit;

#define SHA256_ROTL(a,b) (((a>>(32-b))&(0x7fffffff>>(31-b)))|(a<<b))
#define SHA256_SR(a,b) ((a>>b)&(0x7fffffff>>(b-1)))
#define SHA256_Ch(x,y,z) ((x&y)^((~x)&z))
#define SHA256_Maj(x,y,z) ((x&y)^(x&z)^(y&z))
#define SHA256_E0(x) (SHA256_ROTL(x,30)^SHA256_ROTL(x,19)^SHA256_ROTL(x,10))
#define SHA256_E1(x) (SHA256_ROTL(x,26)^SHA256_ROTL(x,21)^SHA256_ROTL(x,7))
#define SHA256_sig0(x) (SHA256_ROTL(x,25)^SHA256_ROTL(x,14)^SHA256_SR(x,3))
#define SHA256_sig1(x) (SHA256_ROTL(x,15)^SHA256_ROTL(x,13)^SHA256_SR(x,10))

string s;//s为消息
messagebit message;
bitset<512> message_block[10];

//sha-256的8个哈希初值,对自然数的前八个质数的平方根小数取前32bit

unsigned int consthash[64] = {
    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
};//sha256的64个哈希常量,对自然数前64个质数的立方根取前32bit

void messagespace(){
    int bubit;//bubit为补位位数
    for(int i=0;i<s.size();i++){
        byte bs(s[i]);
        message=message<<8;
        for(int j=0;j<8;j++){
            message[j]=bs[j];
        }
    }
    //cout<<message<<endl;
    bubit=((448-8*s.size())%512+512)%512;//填充0和1的位数
//    cout<<bubit<<endl;
    message=message << bubit;
    message.set(bubit-1,1);//置补位最高位为1
    message=message<<64;
    word slenth=8*s.size();//消息的bit长度
    for(int i=0;i<64;i++){
        message[i]=slenth[i];
    }
//    cout<<message<<endl;
};//附加填充数据信息,sha256的消息长度必须要小于2^64

void cutblock(){
    for(int i=s.size()/64+1;i>0;i--){
        for(int j=512*i-1;j>=512*(i-1);j--){
            message_block[s.size()/64+1-i].set(512*i-1-j,message[j]);
//            cout<<message_block[s.size()/64+1-i][j];
        }//s.size()/64+1就是512数据块的总块数,message_block数组装很多块
    }
}


void WT_cycle64(){
    unsigned int H0=0x6a09e667,
     H1=0xbb67ae85,
     H2=0x3c6ef372,
     H3=0xa54ff53a,
     H4=0x510e527f,
     H5=0x9b05688c,
     H6=0x1f83d9ab,
     H7=0x5be0cd19;
    unsigned int T1,T2,A,B,C,D,E,F,G,H;
    for(int i=0;i<s.size()/64+1;i++){
        bitset<32> M[64];
        unsigned int W[64];
        for(int j=0;j<16;j++){
            for(int k=0;k<32;k++){
                M[j].set(31-k,message_block[i][32*j+k]);//分块
//                cout<<M[j][k];
//                cout<<W[j]<<endl;
            }
            W[j]=M[j].to_ulong();
//            cout<<M[j].to_ulong()<<endl;
        }
        //64次循环迭代
        A = H0, B = H1, C = H2, D = H3, E = H4, F = H5, G = H6, H = H7;
        for(int j=16;j<64;j++)
            {
            W[j]=SHA256_sig1(W[j-2])+W[j-7]+SHA256_sig0(W[j-15])+W[j-16];
//            cout<<W[j];
            }

        for (int i = 0;i < 64;i++){
             T1 = H + SHA256_E1(E) + SHA256_Ch(E, F, G) + consthash[i] + W[i];
             T2 = SHA256_E0(A) + SHA256_Maj(A, B, C);
             H = G, G = F, F = E, E = D + T1, D = C, C = B, B = A, A = T1 + T2;
         }
         H0 += A, H1 += B, H2 += C, H3 += D, H4 += E, H5 += F, H6 += G, H7 += H;
    }
    cout<<"经过sha256后的密文:";
    cout<<hex<<H0;
    cout<<hex<<H1;
    cout<<hex<<H2;
    cout<<hex<<H3;
    cout<<hex<<H3;
    cout<<hex<<H5;
    cout<<hex<<H6;
    cout<<hex<<H7;

}



int main(){
    cout<<"请输入你要加密的消息"<<endl;
    getline(cin,s); 
//mlen/64 +1为需要的空间长度
    cout<<"你的消息为"<<s<<endl;
    messagespace();
    cutblock();
    WT_cycle64();
    return 0;
}

验证图片
抄作业改下函数
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值