shapp——一个计算sha256的命令行小工具的实现

来源:互联网 发布:淘宝网店如何加盟 编辑:程序博客网 时间:2024/06/08 09:26

此工具从openssl源码中抠出部分代码,实现了一个类sha256。代码是匆匆从openssl里面抠出来的,没有经过细心整理。

头文件:sha256.h

#pragma once #include <string>  #define SHA_LONG unsigned int  #define SHA_LBLOCK  16//#define SHA_LAST_BLOCK  (SHA_CBLOCK-8) #define SHA256_CBLOCK   (SHA_LBLOCK*4)  /* SHA-256 treats input data as a                     * contiguous array of 32 bit                     * wide big-endian values. */#define SHA256_DIGEST_LENGTH    32  #define DATA_ORDER_IS_BIG_ENDIAN  typedef struct SHA256state_st    {    SHA_LONG h[8];    SHA_LONG Nl,Nh;    SHA_LONG data[SHA_LBLOCK];    unsigned int num,md_len;    } SHA256_CTX;//替换定义于通用算法里面的那些宏#define HASH_LONG               SHA_LONG  #define HASH_CTX                SHA256_CTX#define HASH_CBLOCK             SHA256_CBLOCK  #define MD32_REG_T long  #define X(i)    XX##i  #define HASH_MAKE_STRING(c,s)   do {    \    unsigned long ll;       \    unsigned int  nn;       \    for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++)   \        {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \    } while (0)  //来源于md32_common.h的定义,用于大端对齐DATA_ORDER_IS_BIG_ENDIAN#define HOST_c2l(c,l)   (l =(((unsigned long)(*((c)++)))<<24),        \             l|=(((unsigned long)(*((c)++)))<<16),        \             l|=(((unsigned long)(*((c)++)))<< 8),        \             l|=(((unsigned long)(*((c)++)))       ),       \             l)  #define HOST_l2c(l,c)   (*((c)++)=(unsigned char)(((l)>>24)&0xff),    \             *((c)++)=(unsigned char)(((l)>>16)&0xff),    \             *((c)++)=(unsigned char)(((l)>> 8)&0xff),    \             *((c)++)=(unsigned char)(((l)    )&0xff),  \             l)  class sha256{public:    sha256(void);    ~sha256(void);public:    void sha(const std::string& src, std::string& out);private:    int init(SHA256_CTX *c);    int update(SHA256_CTX *c, const void *data_, size_t len);    int final(unsigned char *md, HASH_CTX *c);    void sha256_block_data_order (SHA256_CTX *c, const void *p, size_t num);};

源文件sha256.cpp

#include "StdAfx.h"#include "sha256.h"#include <sstream>#include <iomanip>sha256::sha256(void){}sha256::~sha256(void){}void sha256::sha(const std::string& src, std::string& out) {    SHA256_CTX c;      unsigned char m[SHA256_DIGEST_LENGTH];      memset(m,0,sizeof(m));     init(&c);     update(&c,src.c_str(),src.length());      final(m,&c);      //OPENSSL_cleanse(&c,sizeof(c));      std::stringstream  hex;    char buf[3]= {0};    for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {        memset(buf,0,sizeof(buf));         sprintf_s(buf,sizeof(buf),"%02X",m[i]);        hex<<buf;    }    out = hex.str();}int sha256::init(SHA256_CTX *c) {     memset (c,0,sizeof(*c));    c->h[0]=0x6a09e667UL;   c->h[1]=0xbb67ae85UL;    c->h[2]=0x3c6ef372UL;   c->h[3]=0xa54ff53aUL;    c->h[4]=0x510e527fUL;   c->h[5]=0x9b05688cUL;    c->h[6]=0x1f83d9abUL;   c->h[7]=0x5be0cd19UL;    c->md_len=SHA256_DIGEST_LENGTH;    return 1;}//通用的算法,定义于openssl/md32_common.h 的HASH_UPDATE#define HASH_BLOCK_DATA_ORDER   sha256_block_data_orderint sha256::update(SHA256_CTX *c, const void *data_, size_t len) {    const unsigned char *data=(const unsigned char *)data_;    unsigned char *p;    HASH_LONG l;    size_t n;    if (len==0) return 1;    l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL;    /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to     * Wei Dai <weidai@eskimo.com> for pointing it out. */    if (l < c->Nl) /* overflow */        c->Nh++;    c->Nh+=(HASH_LONG)(len>>29);    /* might cause compiler warning on 16-bit */    c->Nl=l;    n = c->num;    if (n != 0)        {        p=(unsigned char *)c->data;        if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)            {            memcpy (p+n,data,HASH_CBLOCK-n);            HASH_BLOCK_DATA_ORDER (c,p,1);            n      = HASH_CBLOCK-n;            data  += n;            len   -= n;            c->num = 0;            memset (p,0,HASH_CBLOCK);   /* keep it zeroed */            }        else            {            memcpy (p+n,data,len);            c->num += (unsigned int)len;            return 1;            }        }    n = len/HASH_CBLOCK;    if (n > 0)        {        HASH_BLOCK_DATA_ORDER (c,data,n);        n    *= HASH_CBLOCK;        data += n;        len  -= n;        }    if (len != 0)        {        p = (unsigned char *)c->data;        c->num = (unsigned int)len;        memcpy (p,data,len);        }    return 1;}//也是md32_commmon.h中的通用算法int sha256::final(unsigned char *md, HASH_CTX *c) {    unsigned char *p = (unsigned char *)c->data;    size_t n = c->num;    p[n] = 0x80; /* there is always room for one */    n++;    if (n > (HASH_CBLOCK-8))        {        memset (p+n,0,HASH_CBLOCK-n);        n=0;        HASH_BLOCK_DATA_ORDER (c,p,1);        }    memset (p+n,0,HASH_CBLOCK-8-n);    p += HASH_CBLOCK-8;#if   defined(DATA_ORDER_IS_BIG_ENDIAN)    (void)HOST_l2c(c->Nh,p);    (void)HOST_l2c(c->Nl,p);#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)    (void)HOST_l2c(c->Nl,p);    (void)HOST_l2c(c->Nh,p);#endif    p -= HASH_CBLOCK;    HASH_BLOCK_DATA_ORDER (c,p,1);    c->num=0;    memset (p,0,HASH_CBLOCK);#ifndef HASH_MAKE_STRING#error "HASH_MAKE_STRING must be defined!"#else    HASH_MAKE_STRING(c,md);#endif    return 1; }static const SHA_LONG K256[64] = {    0x428a2f98UL,0x71374491UL,0xb5c0fbcfUL,0xe9b5dba5UL,    0x3956c25bUL,0x59f111f1UL,0x923f82a4UL,0xab1c5ed5UL,    0xd807aa98UL,0x12835b01UL,0x243185beUL,0x550c7dc3UL,    0x72be5d74UL,0x80deb1feUL,0x9bdc06a7UL,0xc19bf174UL,    0xe49b69c1UL,0xefbe4786UL,0x0fc19dc6UL,0x240ca1ccUL,    0x2de92c6fUL,0x4a7484aaUL,0x5cb0a9dcUL,0x76f988daUL,    0x983e5152UL,0xa831c66dUL,0xb00327c8UL,0xbf597fc7UL,    0xc6e00bf3UL,0xd5a79147UL,0x06ca6351UL,0x14292967UL,    0x27b70a85UL,0x2e1b2138UL,0x4d2c6dfcUL,0x53380d13UL,    0x650a7354UL,0x766a0abbUL,0x81c2c92eUL,0x92722c85UL,    0xa2bfe8a1UL,0xa81a664bUL,0xc24b8b70UL,0xc76c51a3UL,    0xd192e819UL,0xd6990624UL,0xf40e3585UL,0x106aa070UL,    0x19a4c116UL,0x1e376c08UL,0x2748774cUL,0x34b0bcb5UL,    0x391c0cb3UL,0x4ed8aa4aUL,0x5b9cca4fUL,0x682e6ff3UL,    0x748f82eeUL,0x78a5636fUL,0x84c87814UL,0x8cc70208UL,    0x90befffaUL,0xa4506cebUL,0xbef9a3f7UL,0xc67178f2UL };//来源于md32_common.h#define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))  //来源于sha256.c#define Sigma0(x)   (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10))#define Sigma1(x)   (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7))#define sigma0(x)   (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3))#define sigma1(x)   (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10))#define Ch(x,y,z)   (((x) & (y)) ^ ((~(x)) & (z)))#define Maj(x,y,z)  (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))#define ROUND_00_15(i,a,b,c,d,e,f,g,h)      do {    \    T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];  \    h = Sigma0(a) + Maj(a,b,c);         \    d += T1;    h += T1;        } while (0)#define ROUND_16_63(i,a,b,c,d,e,f,g,h,X)    do {    \    s0 = X[(i+1)&0x0f]; s0 = sigma0(s0);    \    s1 = X[(i+14)&0x0f];    s1 = sigma1(s1);    \    T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];    \    ROUND_00_15(i,a,b,c,d,e,f,g,h);     } while (0)//sha算法自己实现sha256_block_data_order用来替换通用算法中的HASH_BLOCK_DATA_ORDERvoid sha256::sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num)    {    unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1;    SHA_LONG    X[16];    int i;    const unsigned char *data=(const unsigned char *)in;    const union { long one; char little; } is_endian = {1};            while (num--) {    a = ctx->h[0];  b = ctx->h[1];  c = ctx->h[2];  d = ctx->h[3];    e = ctx->h[4];  f = ctx->h[5];  g = ctx->h[6];  h = ctx->h[7];    if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)in%4)==0)        {        const SHA_LONG *W=(const SHA_LONG *)data;        T1 = X[0] = W[0];   ROUND_00_15(0,a,b,c,d,e,f,g,h);        T1 = X[1] = W[1];   ROUND_00_15(1,h,a,b,c,d,e,f,g);        T1 = X[2] = W[2];   ROUND_00_15(2,g,h,a,b,c,d,e,f);        T1 = X[3] = W[3];   ROUND_00_15(3,f,g,h,a,b,c,d,e);        T1 = X[4] = W[4];   ROUND_00_15(4,e,f,g,h,a,b,c,d);        T1 = X[5] = W[5];   ROUND_00_15(5,d,e,f,g,h,a,b,c);        T1 = X[6] = W[6];   ROUND_00_15(6,c,d,e,f,g,h,a,b);        T1 = X[7] = W[7];   ROUND_00_15(7,b,c,d,e,f,g,h,a);        T1 = X[8] = W[8];   ROUND_00_15(8,a,b,c,d,e,f,g,h);        T1 = X[9] = W[9];   ROUND_00_15(9,h,a,b,c,d,e,f,g);        T1 = X[10] = W[10]; ROUND_00_15(10,g,h,a,b,c,d,e,f);        T1 = X[11] = W[11]; ROUND_00_15(11,f,g,h,a,b,c,d,e);        T1 = X[12] = W[12]; ROUND_00_15(12,e,f,g,h,a,b,c,d);        T1 = X[13] = W[13]; ROUND_00_15(13,d,e,f,g,h,a,b,c);        T1 = X[14] = W[14]; ROUND_00_15(14,c,d,e,f,g,h,a,b);        T1 = X[15] = W[15]; ROUND_00_15(15,b,c,d,e,f,g,h,a);        data += SHA256_CBLOCK;        }    else        {        SHA_LONG l;        HOST_c2l(data,l); T1 = X[0] = l;  ROUND_00_15(0,a,b,c,d,e,f,g,h);        HOST_c2l(data,l); T1 = X[1] = l;  ROUND_00_15(1,h,a,b,c,d,e,f,g);        HOST_c2l(data,l); T1 = X[2] = l;  ROUND_00_15(2,g,h,a,b,c,d,e,f);        HOST_c2l(data,l); T1 = X[3] = l;  ROUND_00_15(3,f,g,h,a,b,c,d,e);        HOST_c2l(data,l); T1 = X[4] = l;  ROUND_00_15(4,e,f,g,h,a,b,c,d);        HOST_c2l(data,l); T1 = X[5] = l;  ROUND_00_15(5,d,e,f,g,h,a,b,c);        HOST_c2l(data,l); T1 = X[6] = l;  ROUND_00_15(6,c,d,e,f,g,h,a,b);        HOST_c2l(data,l); T1 = X[7] = l;  ROUND_00_15(7,b,c,d,e,f,g,h,a);        HOST_c2l(data,l); T1 = X[8] = l;  ROUND_00_15(8,a,b,c,d,e,f,g,h);        HOST_c2l(data,l); T1 = X[9] = l;  ROUND_00_15(9,h,a,b,c,d,e,f,g);        HOST_c2l(data,l); T1 = X[10] = l; ROUND_00_15(10,g,h,a,b,c,d,e,f);        HOST_c2l(data,l); T1 = X[11] = l; ROUND_00_15(11,f,g,h,a,b,c,d,e);        HOST_c2l(data,l); T1 = X[12] = l; ROUND_00_15(12,e,f,g,h,a,b,c,d);        HOST_c2l(data,l); T1 = X[13] = l; ROUND_00_15(13,d,e,f,g,h,a,b,c);        HOST_c2l(data,l); T1 = X[14] = l; ROUND_00_15(14,c,d,e,f,g,h,a,b);        HOST_c2l(data,l); T1 = X[15] = l; ROUND_00_15(15,b,c,d,e,f,g,h,a);        }    for (i=16;i<64;i+=8)        {        ROUND_16_63(i+0,a,b,c,d,e,f,g,h,X);        ROUND_16_63(i+1,h,a,b,c,d,e,f,g,X);        ROUND_16_63(i+2,g,h,a,b,c,d,e,f,X);        ROUND_16_63(i+3,f,g,h,a,b,c,d,e,X);        ROUND_16_63(i+4,e,f,g,h,a,b,c,d,X);        ROUND_16_63(i+5,d,e,f,g,h,a,b,c,X);        ROUND_16_63(i+6,c,d,e,f,g,h,a,b,X);        ROUND_16_63(i+7,b,c,d,e,f,g,h,a,X);        }    ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;    ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;            }    }

main文件:

// shapp.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "sha256.h"#include <iostream>//http://www.convertstring.com/zh_CN/Hash/SHA256int _tmain(int argc, _TCHAR* argv[]){    //sha256 obj;    //std::string src = "abcdelsjgoaiewfawefa354651g5rse534j35y4li8451h";    //std::string out;    //obj.sha(src,out);    //std::cout<<"source:"<<src<<std::endl;    //std::cout<<"sha256:"<<out<<std::endl;    //while(1) {    //    char c = getchar();    //    if ( c == 'q' || c == 'Q' ) {    //        break;    //    }    //}    while(1) {        std::cout<<"source:";        std::string src;        std::cin>>src;        if (src == "quit") {            break;        }        sha256 obj;        std::string out;        obj.sha(src,out);        std::cout<<"sha256:";        std::cout<<out<<std::endl;    }    return 0;}
0 0