linux md5算法应用

MD5信息摘要算法
(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value)。摘要算法,是一个不可逆过程,就是与数据大小无关,经过算法运算后都是生成固定长度的一组数据,结果为16进制进行显示的128bit的二进制串。通常表示为32个十六进制数连成的字符串。
一、linux md5的应用
1、使用mdsum命令
echo -n “abcdefg” | md5sum |tr a-z A-Z
输出结果:7AC66C0F148DE9519B8BD264312C4D64
2、使用openssl md5
echo -n “abcdefg” | openssl md5 |tr a-z A-Z
输出同样结果:7AC66C0F148DE9519B8BD264312C4D64
注释:
-n 参数,强制去掉echo时回车,不然输出结果是错误的。
|tr a-z A-Z 参数,将输出结果转化为大写字母。
3、使用标准C测试
调用库 #include<openssl/md5.h>
主要用下面几个函数
数据大的话用下面三个函数。
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
很简单的一组字符串可以直接用下面这个函数。
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
写完代码,编译时需加参数-lcrypto调用openssl动态库,不然会出错
gcc -lcrypto test.c -o test
md5.h库内容显示如下:

/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */
#ifndef HEADER_MD5_H
# define HEADER_MD5_H
# include <openssl/opensslconf.h>
# ifndef OPENSSL_NO_MD5
# include <openssl/e_os2.h>
# include <stddef.h>
# ifdef  __cplusplus
extern "C" {
    
    
# endif
/*
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * ! MD5_LONG has to be at least 32 bits wide.                     !
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 */
# define MD5_LONG unsigned int
# define MD5_CBLOCK      64
# define MD5_LBLOCK      (MD5_CBLOCK/4)
# define MD5_DIGEST_LENGTH 16
typedef struct MD5state_st {
    
    
    MD5_LONG A, B, C, D;
    MD5_LONG Nl, Nh;
    MD5_LONG data[MD5_LBLOCK];
    unsigned int num;
} MD5_CTX;
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
void MD5_Transform(MD5_CTX *c, const unsigned char *b);
# ifdef  __cplusplus
}
# endif
# endif
#endif

例子:vi md5.c

#include<stdio.h>
#include<string.h>
#include<openssl/md5.h>
void test1()
{
    
    
    unsigned char *str= "20:35:6E:18:2A:86";
    unsigned char md[16];
    int i;
    char temp[3];
    char code[33];
    MD5(str,strlen(str),md);
    for (i = 0; i < 16; i++){
    
    
        sprintf(temp,"%2.2X",md[i]);
        strcat(code,temp);
    }
    printf("test1 str to code:%s\n",code);
}
void test2()
{
    
    
    MD5_CTX ctx;
    unsigned char *str= "20:35:6E:18:2A:86";
    unsigned char md[16];
    int i;
    char temp[3];
    char code[33];
    MD5_Init(&ctx);
    MD5_Update(&ctx,str,strlen(str));
    MD5_Final(md,&ctx);
    for( i=0; i<16; i++ ){
    
    
        sprintf(temp,"%02X",md[i]);
        strcat(code,temp);
    }
    printf("test2 str to code:%s\n",code);
}
int main( int argc, char **argv )
{
    
    
	test1();
	test2();
    return 0;
}

输出结果:

test1 str to code:2C0EC30AA819B957D997343135D5268B
test2 str to code:2C0EC30AA819B957D997343135D5268B

二、实用栗子
自定算法简易描述如下:

1、列出设备网络MAC字符串
2、以某种方式生成一个随机数
3、将生成的随机数按既定方式混入MAC字符串中
4、然后将字符串的头部增加固定字符,尾部增加固定字符,连接生成一个新字符串。
5、将新字符串使用md5算法计算出一组32位hex字符串
6、把32个字符串分解为32个整型数据,依次乘以一个定值,循环累加。
7、将最终的累加值以字符串形式输出。
三、具体代码
下面代码在openEuler环境下用gcc和termux环境下用clang均通过测试,仅供学习参考研究,不作他用。
vi test.c
gcc -lcrypto test.c -o test

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/md5.h>
//#pragma clang diagnostic ignored "-Wpointer-sign"
//gcc md5.c -o ~/md5  -lcrypto
char *mac_str(char *mac,char *rand)
{
    
    
    int     i,mac_len,rand_len,offset;
    char    mac_b[50];
    char    temp[4];
    char    mac1[19];
    char    rand1[7];
    strcpy(mac1,mac);
    strcpy(rand1,rand);
    rand_len= strlen(rand);
    mac_len = strlen(mac);
    mac[mac_len-1] = rand[rand_len-1];
    offset = 0;
    for (i=0;i<mac_len;i++)
    {
    
    
        if (mac[i] == ':')
        {
    
    
            mac[i] = rand[offset];
            offset += 1;
        }
    }
    if (rand[0] == 'C')
    {
    
    
        for (i=0;i<mac_len;i++)
        {
    
    
            sprintf(temp,"%d",mac[i]);
            strcat(mac_b,temp);
        }
    }
    return mac;
}

int adb_key(char *rand_s,char *mac_s)
{
    
    
    char r[7],m[19];
    char buf[50];
    int i,result;
    char p[10];
    char str[50];
    unsigned char buf_u[50];
    unsigned char md_u[16];
    strcpy(r,rand_s);
    strcpy(m,mac_s);
    sprintf(buf,"linux%s@%sHW_openEuler",r,m);
    for (i=0;i<strlen(buf);i++)
    {
    
    
        buf_u[i]=(int)buf[i];
    }
    MD5(buf_u,strlen(buf),md_u);
    str[0]='\0';
    for (i=0;i<sizeof(md_u);i++)
    {
    
    
        p[0]='\0';
        sprintf(p,"%2.2X",md_u[i]);
        strcat(str,p);
    }
    result=0;
    for (i=0;i<strlen(str);i++)
    {
    
    
       result=(int)(str[i])+31*result;
    }
    if (result<0)
        result=-result;
    return result;
}
int main(int argc, char* argv[])
{
    
    
    char input_mac[19];
    char input_rand[7];
    char check[19];
    int  key;
    printf("input mac press enter,for example:04:15:A3:3E:58:8A\n");
    scanf("%s",input_mac);
    printf("input rand press enter,for example:C78369\n");
    scanf("%s",input_rand);
	strcpy(check,mac_str(input_mac,input_rand));
    key=adb_key(input_rand,check);
    printf("Success! key is:\n%d\n",key);
} 

猜你喜欢

转载自blog.csdn.net/lenovo8088/article/details/115251503