BIGNUM转换成16进制并用字符串保存以及md5算法基于c语言和openssl编程

     md5算法在openssl下的实现这里就不具体了,下面代的功能是随机生成一个bignum型的大数,将大数(保存大数的部分是unsignedlong转换16制然后保存在字符串中,再把字符串做md5运算,得到摘要。

     int sprintf(char *buffer,const char *format, [argument]

     指的是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个参函数。使用sprintf对于写入buffer的字符数是没有限制的,就存在了buffer溢出的可能性。

     要介的是字符数的一个情况,’\0’也要占一个地方,也就是char a[5] = “abcde”这样报错,只能保存4个字符。

     我的运行境中char占一个字,int占4个字,unsigned long 占8个字下面设计程序很重要,再附上一个范表。

    

     

     生成的大数指定了是512个位度,而一个unsigned long 64个位,也就是生成的大数里面指向unsigned long的指占了8unsigned long

     依次8unsigned long,循八次。

     又要考unsigned long 转换int 里直接转换写成 sprintf(temp1,"%016X",a->d[i]); 会有两个问题。第一个问题16

算机上没法表示,算机最大的是16进制只有F,第二个问题unsigned long的范int的范大太多,会掉很多数据。

     所以就分两次每次一半,十个数。我看到unsignedlong的最大18446744073709551615一共20个数,unsigned int的最大4294967295,前十个数不会失真,但后面十个数大于了int所能表达的范围。

     那后面的十个数只能再分开取了,理所当的把存它的temp2成temp2[5],要往里面放4个char,20个数的候是64位,10个数是32位,5个数是16位。这样想就了。

     可以算一下4个char,一个char 是4位,那一共是16位,可以表示的最大是2的16次方减1,表可知是65536,意思就是

如果个五个数大于65536了,就存不下了,会报错,数越界,于是我只能多分配一个char,定义为temp[6],用5个char来存

放,这样能存的最大是2的20次方减1,足了。

    Openssl程中md5摘要的果是128位,设计过程和上面一

   下面是本人写的源代码

#include <stdio.h>
#include <openssl/md5.h>
#include <string.h>
#include <openssl/bn.h>
//随机产生一个大数 用md5转换成摘要
int main(int argc, const char * argv[]) {
    int i;
    //产生大数
    BIGNUM *a;
    char temp[3] = {0};
    char temp1[9] = {0};
    char temp2[6] = {0};
    unsigned char md[16] = {0};
    MD5_CTX ctx;
    char data[150] = {0};
    unsigned long  tempnum;
    a = BN_new();
    BN_rand(a,512,0,0);//生成的大数占512个字节
    printf("%lu\n",(a->d[0])%10000000000);
    for(i= 0;i<8;i++)//不会溢出
    {
        tempnum = (a->d[i])%10000000000;
        sprintf(temp1,"%08X",(a->d[i])/10000000000);
        strcat(data, temp1);
        sprintf(temp2,"%04X",tempnum/100000);
        strcat(data, temp2);
        sprintf(temp2,"%04X",tempnum%100000);
        strcat(data, temp2);
    }
    printf("随机产生的大数转化成16进制后保存为:%s\n占了:%d个char\n",data,strlen(data));
    //md5操作
    MD5_Init(&ctx);
    MD5_Update(&ctx, data,strlen(data));
    MD5_Final(md, &ctx);
    
    char buf[33] = {0};
    for (i=0;i<16;i++)
    {
        sprintf(temp, "%02X",md[i]);
        strcat(buf, temp);
        
    }
    printf("md5哈希后的摘要为:%s\n",buf);
    return 0;
}
    运行结果:

  

     分析一下结果,第一个是用来验证的,是第一个unsigned long的后十位。4140512874,所以应该对应了8个16制的。也就是A1BD324A。我算一下前面4位16制A1BD是否等于十制的41405果是相同的,所以程序是正确的。

猜你喜欢

转载自blog.csdn.net/nanshenyaohaohaode/article/details/79098589