#include <iostream> #include <string> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <math.h> #define SINGLE_ONE_BIT 0x80 #define BLOCK_SIZE 512 #define MOD_SIZE 448 #define APP_SIZE 64 #define BITS 8 // MD5 Chaining Variable #define A 0x67452301UL #define B 0xEFCDAB89UL #define C 0x98BADCFEUL #define D 0x10325476UL // Creating own types #ifdef UINT64 # undef UINT64 #endif #ifdef UINT32 # undef UINT32 #endif typedef unsigned long long UINT64; //typedef unsigned long UINT32; typedef unsigned char UINT8; #pragma pack(1) using namespace std; /********** 计算rfesponse *************/ typedef struct { char * message; UINT64 length; }STRING; const UINT32 X[4][2] = {{0, 1}, {1, 5}, {5, 3}, {0, 7}}; // Constants for MD5 transform routine. const UINT32 S[4][4] = { { 7, 12, 17, 22 }, { 5, 9, 14, 20 }, { 4, 11, 16, 23 }, { 6, 10, 15, 21 } }; // F, G, H and I are basic MD5 functions. UINT32 F( UINT32 X, UINT32 Y, UINT32 Z ) { return ( X & Y ) | ( ~X & Z ); } UINT32 G( UINT32 X, UINT32 Y, UINT32 Z ) { return ( X & Z ) | ( Y & ~Z ); } UINT32 H( UINT32 X, UINT32 Y, UINT32 Z ) { return X ^ Y ^ Z; } UINT32 I( UINT32 X, UINT32 Y, UINT32 Z ) { return Y ^ ( X | ~Z ); } // rotates x left s bits. UINT32 rotate_left( UINT32 x, UINT32 s ) { return ( x << s ) | ( x >> ( 32 - s ) ); } // Pre-processin UINT32 count_padding_bits ( UINT32 length ) { UINT32 div = length * BITS / BLOCK_SIZE; UINT32 mod = length * BITS % BLOCK_SIZE; UINT32 c_bits; if ( mod == 0 ) c_bits = MOD_SIZE; else c_bits = ( MOD_SIZE + BLOCK_SIZE - mod ) % BLOCK_SIZE; return c_bits / BITS; } STRING append_padding_bits ( char * argv ) { UINT32 msg_length = strlen ( argv ); UINT32 bit_length = count_padding_bits ( msg_length ); UINT64 app_length = msg_length * BITS; STRING string; string.message = (char *)malloc(msg_length + bit_length + APP_SIZE / BITS); // Save message strncpy ( string.message, argv, msg_length ); // Pad out to mod 64. memset ( string.message + msg_length, 0, bit_length ); string.message [ msg_length ] = SINGLE_ONE_BIT; // Append length (before padding). memmove ( string.message + msg_length + bit_length, (char *)&app_length, sizeof( UINT64 ) ); string.length = msg_length + bit_length + sizeof( UINT64 ); return string; } //获取 response argc写2,argv[0]="" argv[1]="xxx" xxx为输入的字符 string MD5(int argc, char *argv[]) { string md5; string md; UINT32 p[16]; UINT8 q[32]; STRING string; UINT32 w[16]; UINT32 chain[4]; UINT32 state[4]; UINT8 r[16]; UINT32 ( *auxi[ 4 ])( UINT32, UINT32, UINT32 ) = { F, G, H, I }; int roundIdx; int argIdx; int sIdx; int wIdx; int i; int j; if ( argc < 2 ) { fprintf ( stderr, "usage: %s string ...\n", argv[ 0 ] ); return 0; } for ( argIdx = 1; argIdx < argc; argIdx++ ) { string = append_padding_bits ( argv[ argIdx ] ); // MD5 initialization. chain[0] = A; chain[1] = B; chain[2] = C; chain[3] = D; for ( j = 0; j < string.length; j += BLOCK_SIZE / BITS) { memmove ( (char *)w, string.message + j, BLOCK_SIZE / BITS ); memmove ( state, chain, sizeof(chain) ); for ( roundIdx = 0; roundIdx < 4; roundIdx++ ) { wIdx = X[ roundIdx ][ 0 ]; sIdx = 0; for ( i = 0; i < 16; i++ ) { // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. // Rotation is separate from addition to prevent recomputation. state[sIdx] = state [ (sIdx + 1) % 4 ] + rotate_left ( state[sIdx] + ( *auxi[ roundIdx ] ) ( state[(sIdx+1) % 4], state[(sIdx+2) % 4], state[(sIdx+3) % 4]) + w[ wIdx ] + (UINT32)floor( (1ULL << 32) * fabs(sin(double(roundIdx * 16 + i + 1))) ), S[ roundIdx ][ i % 4 ]); sIdx = ( sIdx + 3 ) % 4; wIdx = ( wIdx + X[ roundIdx ][ 1 ] ) & 0xF; } } chain[ 0 ] += state[ 0 ]; chain[ 1 ] += state[ 1 ]; chain[ 2 ] += state[ 2 ]; chain[ 3 ] += state[ 3 ]; } memmove ( r + 0, (char *)&chain[0], sizeof(UINT32) ); memmove ( r + 4, (char *)&chain[1], sizeof(UINT32) ); memmove ( r + 8, (char *)&chain[2], sizeof(UINT32) ); memmove ( r + 12, (char *)&chain[3], sizeof(UINT32) ); for ( i = 0; i < 16; i++ ) { printf ( "%02x", r[i] ); p[i]=(UINT32)r[i]; } putchar ( '\n' ); for ( i = 0; i < 16; i++ ) { //printf ( "%02x", p[i] ); q[i*2]=p[i]/16; q[i*2+1]=p[i]%16; } for ( i = 0; i < 32; i++ ) { //printf ( "%x", q[i]); //putchar ( '\n' ); if(q[i]>=0&q[i]<=9) md=q[i]+'0'; else md=q[i]-10+'a'; md5=md5+md; } cout<<md5<<endl; return md5; } } string GetResponse(string username,string realm,string password,string method,string uri,string nonce) { string HA1,HA2,Response,temp; const char *HA_1; const char *HA_2; char *arg1[2]; arg1[0] = " "; //HA1 = md5("username:realm:password"); temp=username+":"+realm+":"+password; arg1[1]=(char *)temp.data();//需要计算字符传入 cout<<"arg1[1]="<<arg1[1]<<endl; HA1 = MD5(2,arg1); HA_1=HA1.data(); // HA2 = md5("method:uri");//method为下次发送数据的方法头,如下例为"GET",一般SIP注册为"REGISTER";uri 为请求的实际路径; //arg1[1] =const_cast<char*>((method_1+":"+uri_1).data());//需要计算字符传入 //arg1[1]="REGISTER:sip:192.168.20.233"; temp=method+":"+uri; arg1[1]=(char *)temp.data();//需要计算字符传入 cout<<"arg1[1]="<<arg1[1]<<endl; HA2 = MD5(2,arg1); HA_2=HA2.data(); //response = md5("HA1:nouce:HA2"); Response=HA1+":"+nonce+":"+HA2; arg1[1]=(char *)(Response.data()); cout<<"arg1[1]="<<arg1[1]<<endl; Response=MD5(2,arg1); cout<<"HA1="<<HA1<<endl; cout<<"HA2="<<HA2<<endl; cout<<"Response="<<Response<<endl; return Response; }