C、C++的Makefile的编写以及动、静态库的制作调用(包括MAC地址的获取及MD5加密)
一、C代码
静态库
四个.h.c文件
add.h
1 #ifndef ADD_H 2 #define ADD_H 3 4 int add(int a,int b); 5 6 #endif
add.c
1 #include <stdio.h> 2 3 int add(int a,int b) 4 { 5 printf("%d %d\n",a,b); 6 return (a + b); 7 }
decrease.h
1 #ifndef DECREASE_H 2 #define DECREASE_H 3 4 int decrease(int a,int b); 5 6 #endif
decrease.c
1 #include <stdio.h> 2 3 int decrease(int a,int b) 4 { 5 printf("%d %d\n",a,b); 6 return (a - b); 7 }
multiply.h
1 #ifndef MULTIPLY_H 2 #define MULTIPLY_H 3 4 int multiply(int a,int b); 5 6 #endif
multiply.c
1 #include <stdio.h> 2 3 int multiply(int a,int b) 4 { 5 printf("%d %d\n",a,b); 6 return (a * b); 7 }
divide.h
1 #ifndef DIVIDE_H 2 #define DIVIDE_H 3 4 float divide(float a,int b); 5 6 #endif
divide.c
1 #include <stdio.h> 2 3 int divide(int a,int b) 4 { 5 printf("%d %d\n",a,b); 6 return (a / b); 7 }
编译成静态库的命令:
1 gcc -c add.c decrease.c multiply.c divide.c 2 ar -rv libarithmetic.a add.o decrease.o multiply.o divide.o
若想要在main.c文件中调用
1 #include <stdio.h> 2 3 int main(int argc,char **argv) 4 { 5 int a = add(3,5); 6 int b = decrease(8,6); 7 int c = multiply(5,7); 8 int d = divide(15,2); 9 printf("%d %d %d %d\n",a,b,c,d); 10 return 0; 11 }
编译时使用命令
1 gcc -o hello main.c -L /home/jason/share/test/Makefile/static/lib -larithmetic
编译成动态库的命令
1 gcc add.c decrease.c multiply.c divide.c -fPIC -shared -o libmyhello.so
main.c调用
1 gcc -o main main.c -L/home/jason/share/test/Makefile/share/lib -lmyhello
终端导入路径:
1 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/jason/share/test/Makefile/share/lib
Makefile的编写
在hello.c文件里调用静态库libarithmetic.a
main.c
1 #include <stdio.h> 2 3 int main(int argc,char **argv) 4 { 5 hello("everyone"); 6 return 0; 7 }
hello.c
1 #include <stdio.h> 2 3 void hello(const char *name) 4 { 5 printf("Hello %s!\n",name); 6 int a = add(3,5); 7 int b = decrease(8,6); 8 int c = multiply(5,7); 9 int d = divide(15,2); 10 printf("%d %d %d %d\n",a,b,c,d); 11 }
Makefile
1 CC = gcc 2 CXX = g++ 3 4 LIBS = -static -L/home/jason/share/test/Makefile/static/lib -larithmetic 5 6 OBJ = admdtest 7 8 OBJ_SOURCE = main.c \ 9 hello.c 10 11 $(OBJ):$(OBJ_SOURCE) 12 $(CC) -o $@ $(OBJ_SOURCE) $(LIBS) 13 14 15 clean: 16 rm -f *.o $(OBJ)
动态库调用的Makefile
1 CC = gcc 2 CXX = g++ 3 4 LIBS = -L/home/jason/share/test/Makefile/share/lib -lmyhello 5 6 OBJ = admdtest 7 8 OBJ_SOURCE = main.c \ 9 hello.c 10 11 $(OBJ):$(OBJ_SOURCE) 12 $(CC) -o $@ $(OBJ_SOURCE) $(LIBS) 13 14 15 clean: 16 rm -f *.o $(OBJ)
并在终端导入环境:
1 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/jason/share/test/Makefile/share/lib
二、C++代码
md5.h
1 #ifndef MD5_H 2 #define MD5_H 3 4 #include <string> 5 #include <fstream> 6 7 /* Type define */ 8 typedef unsigned char byte; 9 typedef unsigned long ulong; 10 11 using std::string; 12 using std::ifstream; 13 14 /* MD5 declaration. */ 15 class MD5 16 { 17 public: 18 MD5(); 19 MD5(const void *input, size_t length); 20 MD5(const string &str); 21 MD5(ifstream &in); 22 void update(const void *input, size_t length); 23 void update(const string &str); 24 void update(ifstream &in); 25 const byte* digest(); 26 string toString(); 27 void reset(); 28 void PrintMD5(const string &str, MD5 &md5); 29 private: 30 void update(const byte *input, size_t length); 31 void final(); 32 void transform(const byte block[64]); 33 void encode(const ulong *input, byte *output, size_t length); 34 void decode(const byte *input, ulong *output, size_t length); 35 string bytesToHexString(const byte *input, size_t length); 36 37 /* class uncopyable */ 38 MD5(const MD5&); 39 MD5& operator=(const MD5&); 40 private: 41 ulong _state[4]; /* state (ABCD) */ 42 ulong _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ 43 byte _buffer[64]; /* input buffer */ 44 byte _digest[16]; /* message digest */ 45 bool _finished; /* calculate finished ? */ 46 47 static const byte PADDING[64]; /* padding for calculate */ 48 static const char HEX[16]; 49 static const size_t BUFFER_SIZE = 1024; 50 }; 51 52 #endif/*MD5_H*/
md5.cpp
1 #include "md5.h" 2 #include <iostream> 3 #include <string.h> 4 #include <stdlib.h> 5 6 using namespace std; 7 8 /* Constants for MD5Transform routine. */ 9 #define S11 7 10 #define S12 12 11 #define S13 17 12 #define S14 22 13 #define S21 5 14 #define S22 9 15 #define S23 14 16 #define S24 20 17 #define S31 4 18 #define S32 11 19 #define S33 16 20 #define S34 23 21 #define S41 6 22 #define S42 10 23 #define S43 15 24 #define S44 21 25 26 27 /* F, G, H and I are basic MD5 functions. 28 */ 29 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 30 #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 31 #define H(x, y, z) ((x) ^ (y) ^ (z)) 32 #define I(x, y, z) ((y) ^ ((x) | (~z))) 33 34 /* ROTATE_LEFT rotates x left n bits. 35 */ 36 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 37 38 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 39 Rotation is separate from addition to prevent recomputation. 40 */ 41 #define FF(a, b, c, d, x, s, ac) { \ 42 (a) += F ((b), (c), (d)) + (x) + ac; \ 43 (a) = ROTATE_LEFT ((a), (s)); \ 44 (a) += (b); \ 45 } 46 #define GG(a, b, c, d, x, s, ac) { \ 47 (a) += G ((b), (c), (d)) + (x) + ac; \ 48 (a) = ROTATE_LEFT ((a), (s)); \ 49 (a) += (b); \ 50 } 51 #define HH(a, b, c, d, x, s, ac) { \ 52 (a) += H ((b), (c), (d)) + (x) + ac; \ 53 (a) = ROTATE_LEFT ((a), (s)); \ 54 (a) += (b); \ 55 } 56 #define II(a, b, c, d, x, s, ac) { \ 57 (a) += I ((b), (c), (d)) + (x) + ac; \ 58 (a) = ROTATE_LEFT ((a), (s)); \ 59 (a) += (b); \ 60 } 61 62 63 const byte MD5::PADDING[64] = { 0x80 }; 64 const char MD5::HEX[16] = { 65 '0', '1', '2', '3', 66 '4', '5', '6', '7', 67 '8', '9', 'a', 'b', 68 'c', 'd', 'e', 'f' 69 }; 70 71 /* Default construct. */ 72 MD5::MD5() { 73 reset(); 74 } 75 76 /* Construct a MD5 object with a input buffer. */ 77 MD5::MD5(const void *input, size_t length) { 78 reset(); 79 update(input, length); 80 } 81 82 /* Construct a MD5 object with a string. */ 83 MD5::MD5(const string &str) { 84 reset(); 85 update(str); 86 } 87 88 /* Construct a MD5 object with a file. */ 89 MD5::MD5(ifstream &in) { 90 reset(); 91 update(in); 92 } 93 94 /* Return the message-digest */ 95 const byte* MD5::digest() { 96 if (!_finished) { 97 _finished = true; 98 final(); 99 } 100 return _digest; 101 } 102 103 /* Reset the calculate state */ 104 void MD5::reset() { 105 106 _finished = false; 107 /* reset number of bits. */ 108 _count[0] = _count[1] = 0; 109 /* Load magic initialization constants. */ 110 _state[0] = 0x67452301; 111 _state[1] = 0xefcdab89; 112 _state[2] = 0x98badcfe; 113 _state[3] = 0x10325476; 114 } 115 116 /* Updating the context with a input buffer. */ 117 void MD5::update(const void *input, size_t length) { 118 update((const byte*)input, length); 119 } 120 121 /* Updating the context with a string. */ 122 void MD5::update(const string &str) { 123 update((const byte*)str.c_str(), str.length()); 124 } 125 126 /* Updating the context with a file. */ 127 void MD5::update(ifstream &in) { 128 129 if (!in) 130 return; 131 132 std::streamsize length; 133 char buffer[BUFFER_SIZE]; 134 while (!in.eof()) { 135 in.read(buffer, BUFFER_SIZE); 136 length = in.gcount(); 137 if (length > 0) 138 update(buffer, length); 139 } 140 in.close(); 141 } 142 143 /* MD5 block update operation. Continues an MD5 message-digest 144 operation, processing another message block, and updating the 145 context. 146 */ 147 void MD5::update(const byte *input, size_t length) { 148 149 ulong i, index, partLen; 150 151 _finished = false; 152 153 /* Compute number of bytes mod 64 */ 154 index = (ulong)((_count[0] >> 3) & 0x3f); 155 156 /* update number of bits */ 157 if((_count[0] += ((ulong)length << 3)) < ((ulong)length << 3)) 158 _count[1]++; 159 _count[1] += ((ulong)length >> 29); 160 161 partLen = 64 - index; 162 163 /* transform as many times as possible. */ 164 if(length >= partLen) { 165 166 memcpy(&_buffer[index], input, partLen); 167 transform(_buffer); 168 169 for (i = partLen; i + 63 < length; i += 64) 170 transform(&input[i]); 171 index = 0; 172 173 } else { 174 i = 0; 175 } 176 177 /* Buffer remaining input */ 178 memcpy(&_buffer[index], &input[i], length-i); 179 } 180 181 /* MD5 finalization. Ends an MD5 message-_digest operation, writing the 182 the message _digest and zeroizing the context. 183 */ 184 void MD5::final() { 185 186 byte bits[8]; 187 ulong oldState[4]; 188 ulong oldCount[2]; 189 ulong index, padLen; 190 191 /* Save current state and count. */ 192 memcpy(oldState, _state, 16); 193 memcpy(oldCount, _count, 8); 194 195 /* Save number of bits */ 196 encode(_count, bits, 8); 197 198 /* Pad out to 56 mod 64. */ 199 index = (ulong)((_count[0] >> 3) & 0x3f); 200 padLen = (index < 56) ? (56 - index) : (120 - index); 201 update(PADDING, padLen); 202 203 /* Append length (before padding) */ 204 update(bits, 8); 205 206 /* Store state in digest */ 207 encode(_state, _digest, 16); 208 209 /* Restore current state and count. */ 210 memcpy(_state, oldState, 16); 211 memcpy(_count, oldCount, 8); 212 } 213 214 /* MD5 basic transformation. Transforms _state based on block. */ 215 void MD5::transform(const byte block[64]) { 216 217 ulong a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; 218 219 decode(block, x, 64); 220 221 /* Round 1 */ 222 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 223 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 224 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 225 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 226 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 227 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 228 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 229 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 230 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 231 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 232 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 233 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 234 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 235 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 236 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 237 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 238 239 /* Round 2 */ 240 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 241 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 242 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 243 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 244 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 245 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 246 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 247 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 248 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 249 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 250 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 251 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 252 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 253 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 254 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 255 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 256 257 /* Round 3 */ 258 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 259 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 260 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 261 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 262 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 263 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 264 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 265 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 266 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 267 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 268 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 269 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 270 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 271 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 272 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 273 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 274 275 /* Round 4 */ 276 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 277 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 278 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 279 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 280 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 281 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 282 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 283 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 284 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 285 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 286 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 287 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 288 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 289 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 290 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 291 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 292 293 _state[0] += a; 294 _state[1] += b; 295 _state[2] += c; 296 _state[3] += d; 297 } 298 299 /* Encodes input (ulong) into output (byte). Assumes length is 300 a multiple of 4. 301 */ 302 void MD5::encode(const ulong *input, byte *output, size_t length) { 303 304 for(size_t i=0, j=0; j<length; i++, j+=4) { 305 output[j]= (byte)(input[i] & 0xff); 306 output[j+1] = (byte)((input[i] >> 8) & 0xff); 307 output[j+2] = (byte)((input[i] >> 16) & 0xff); 308 output[j+3] = (byte)((input[i] >> 24) & 0xff); 309 } 310 } 311 312 /* Decodes input (byte) into output (ulong). Assumes length is 313 a multiple of 4. 314 */ 315 void MD5::decode(const byte *input, ulong *output, size_t length) { 316 317 for(size_t i=0, j=0; j<length; i++, j+=4) { 318 output[i] = ((ulong)input[j]) | (((ulong)input[j+1]) << 8) | 319 (((ulong)input[j+2]) << 16) | (((ulong)input[j+3]) << 24); 320 } 321 } 322 323 /* Convert byte array to hex string. */ 324 string MD5::bytesToHexString(const byte *input, size_t length) { 325 string str; 326 str.reserve(length << 1); 327 for(size_t i = 0; i < length; i++) { 328 int t = input[i]; 329 int a = t / 16; 330 int b = t % 16; 331 str.append(1, HEX[a]); 332 str.append(1, HEX[b]); 333 } 334 return str; 335 } 336 337 /* Convert digest to string value */ 338 string MD5::toString() 339 { 340 return bytesToHexString(digest(), 16); 341 } 342 343 void PrintMD5(const string &str, MD5 &md5) 344 { 345 cout << "MD5(\"" << str << "\") = " << md5.toString() << endl; 346 }
编译成静态库:
1 g++ -c md5.cpp 2 ar -rv libmd5.a md5.o
在main.cpp里面的调用
1 #include "md5.h" 2 #include <iostream> 3 using namespace std; 4 5 int main(int argc,char **argv) 6 { 7 MD5 md5; 8 const char *livekey = "0090E601F3E9"; 9 md5.update(livekey); 10 cout <<"MD5(\""<<livekey<<"\") = " << md5.toString()<<endl; 11 return 0; 12 }
编译命令:
1 g++ -o main main.cpp -L /home/jason/share/test/c++_lib/static/lib -lmd5
编译成动态库:
1 g++ md5.cpp -fPIC -shared -o libmd5.so
main.cpp调用
1 g++ -o main main.c -L/home/jason/share/test/c++_lib/share/lib -lmd5
Makefile的编写
在main.cpp中调用mac.cpp
1 #include "mac.h" 2 #include <iostream> 3 using namespace std; 4 5 int main(int argc,char **argv) 6 { 7 MAC mac; 8 mac.getMac(); 9 return 0; 10 }
mac.h
1 #ifndef MAC_H 2 #define MAC_H 3 4 #include "md5.h" 5 6 #include <stdio.h> 7 #include <net/if.h> 8 #include <sys/ioctl.h> 9 #include <unistd.h> 10 #include <netinet/in.h> 11 12 #include <string.h> 13 #include <stdlib.h> 14 15 #include <iostream> 16 using namespace std; 17 18 class MAC 19 { 20 public: 21 MAC(); 22 void getMac(); 23 }; 24 25 #endif
mac.cpp
1 #include "mac.h" 2 3 #include <iostream> 4 using namespace std; 5 6 MAC::MAC() 7 { 8 9 } 10 11 void MAC::getMac() 12 { 13 char mac[32]; 14 int sockfd; 15 struct ifreq tmp; 16 char mac_addr[30]; 17 18 sockfd = socket(AF_INET, SOCK_STREAM, 0); 19 if( sockfd < 0) 20 { 21 perror("create socket fail\n"); 22 return ; 23 } 24 25 memset(&tmp,0,sizeof(struct ifreq)); 26 strncpy(tmp.ifr_name,"eth0",sizeof(tmp.ifr_name)-1); 27 if( (ioctl(sockfd,SIOCGIFHWADDR,&tmp)) < 0 ) 28 { 29 printf("mac ioctl error\n"); 30 return ; 31 } 32 33 sprintf(mac_addr, "%02x%02x%02x%02x%02x%02x", 34 (unsigned char)tmp.ifr_hwaddr.sa_data[0], 35 (unsigned char)tmp.ifr_hwaddr.sa_data[1], 36 (unsigned char)tmp.ifr_hwaddr.sa_data[2], 37 (unsigned char)tmp.ifr_hwaddr.sa_data[3], 38 (unsigned char)tmp.ifr_hwaddr.sa_data[4], 39 (unsigned char)tmp.ifr_hwaddr.sa_data[5] 40 ); 41 printf("local mac:%s\n", mac_addr); 42 close(sockfd); 43 memcpy(mac,mac_addr,strlen(mac)); 44 MD5 md5; 45 md5.update(mac); 46 cout <<"MD5(\""<<mac<<"\") = " << md5.toString()<<endl; 47 48 }
md5.h、md5.cpp同上这里省略
Makefile
静态库的调用
1 CC = gcc 2 CXX = g++ 3 4 LIBS = -static -L/home/jason/share/test/c++_Makefile/static/lib -lmd5 5 6 OBJ = main 7 8 OBJ_SOURCE = main.cpp \ 9 mac.cpp 10 11 $(OBJ):$(OBJ_SOURCE) 12 $(CXX) -o $@ $(OBJ_SOURCE) $(LIBS) 13 14 clean: 15 rm -f *.o $(OBJ)
动态库的调用
1 CC = gcc 2 CXX = g++ 3 4 LIBS = -L/home/jason/share/test/c++_Makefile/share/lib -lmd5 5 6 OBJ = main 7 8 OBJ_SOURCE = main.cpp \ 9 mac.cpp 10 11 $(OBJ):$(OBJ_SOURCE) 12 $(CXX) -o $@ $(OBJ_SOURCE) $(LIBS) 13 14 clean: 15 rm -f *.o $(OBJ)
需要在终端导入库环境:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/jason/share/test/c++_Makefile/share/lib
以上代码通过测试