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果是相同的,所以程序是正確的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章