weiyan.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  1. #include <stdio.h>
  2. #include <errno.h>
  3. #include <signal.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include <sys/wait.h>
  8. #include <sys/socket.h>
  9. #include <sys/types.h>
  10. #include <netinet/in.h>
  11. #include <arpa/inet.h>
  12. #include <netdb.h>
  13. #include <stdbool.h>
  14. //#include <conio.h>
  15. #include <fcntl.h>
  16. #include <dirent.h>
  17. #include <pthread.h>
  18. #include <stdio.h>
  19. #include <errno.h>
  20. #include <signal.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #include <sys/wait.h>
  25. #include <sys/socket.h>
  26. #include <sys/types.h>
  27. #include <netinet/in.h>
  28. #include <arpa/inet.h>
  29. #include <netdb.h>
  30. #ifdef __cplusplus
  31. extern "C"{
  32. #endif
  33. char* strstrstr(char* str, char* text, char* rear);//变态级的函数,看了可能会崩溃
  34. char* httppost(char* hostname, char* url, char* cs);//POST方法
  35. char* httpget(const char* hostname, char* url);//GET方法
  36. char* getip(char* hostname);//域名转换IP
  37. int hextoint(char* hex);//16进制字符串转整数
  38. #ifdef __cplusplus
  39. }
  40. #endif
  41. char* httppost(char* hostname, char* url, char* cs){ // POST方法
  42. // sock句柄
  43. int sockfd;
  44. struct sockaddr_in serveraddr;
  45. //两个是同一个类型,可混用,但是会警告
  46. //int addrlen = sizeof(serveraddr);
  47. socklen_t addrlen = sizeof(serveraddr);
  48. if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
  49. //printf("创建网络连接失败---socket error!\n");
  50. return NULL;
  51. }
  52. //C4droid的GCC没有这个函数,编译会报错
  53. //bzero(&serveraddr, addrlen);
  54. //可以使用这个函数
  55. memset(&serveraddr,0,addrlen);
  56. serveraddr.sin_family = AF_INET;
  57. //端口80
  58. serveraddr.sin_port = htons(80);
  59. struct hostent* host;
  60. host = gethostbyname(hostname);
  61. if (host == NULL){
  62. printf("无法解析域名\n");
  63. close(sockfd);
  64. return NULL;
  65. }
  66. struct in_addr ip = *((struct in_addr *)host->h_addr);
  67. //printf("连接服务器:%s\n",inet_ntoa(ip));
  68. serveraddr.sin_addr = ip;
  69. if (connect(sockfd, (struct sockaddr*) & serveraddr, addrlen) < 0){
  70. //printf("连接到服务器失败,connect error!\n");
  71. close(sockfd);
  72. return NULL;
  73. }
  74. //因为懒,所以char[2048]
  75. //可以通过strlen获取参数长度来动态申请内存
  76. char postxyt[2048];
  77. char postsjlen[5];
  78. // 发送数据
  79. //32位要用 "%u" 经测试发现还是long最稳定
  80. //顺利通过 GCC,arm-linux-gcc,arm-linux-gnueabi-gcc,安卓jni 编译 无警告
  81. #if __SIZEOF_LONG__ == 8
  82. sprintf(postsjlen, "%lu", strlen(cs));
  83. #else
  84. sprintf(postsjlen, "%u", strlen(cs));
  85. #endif
  86. memset(postxyt, 0, 2048);
  87. // 追加字符串(请求协议头)
  88. //个人感觉strcat函数比较低效
  89. //用char指针和strcpy函数会比较快
  90. sprintf(postxyt,"POST /%s HTTP/1.1\r\nHost: %s\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent: Mozilla/4.0(compatible)\r\nContent-Length: %ld\r\n\r\n%s\r\n\r\n",url,hostname,strlen(cs),cs);
  91. //别问,问就是 “一切皆文件”
  92. /*
  93. if (write(sockfd, postxyt, strlen(postxyt)) == -1){
  94. //printf("发送失败!错误代码:%d,错误信息:%s\n", errno, strerror(errno));
  95. close(sockfd);
  96. return NULL;
  97. }*/
  98. if (send(sockfd, postxyt, strlen(postxyt),0) == -1){
  99. printf("%d,%s\n", errno, strerror(errno));
  100. close(sockfd);
  101. return NULL;
  102. }
  103. fd_set fds;
  104. struct timeval tv = { 3,0 }; //select等待3秒,3秒轮询,要非阻塞就置0
  105. //非阻塞需要循环
  106. FD_ZERO(&fds); //每次循环都要清空集合,否则不能检测描述符变化
  107. FD_SET(sockfd, &fds); //添加描述符
  108. if (select(sockfd + 1, &fds, NULL, NULL, &tv) < 1){
  109. //非阻塞时使用continue;
  110. //-1错误
  111. //0无写入数据
  112. close(sockfd);
  113. return NULL;
  114. }
  115. if (FD_ISSET(sockfd, &fds)) { //测试sock是否可读,即是否网络上有数据
  116. char xyt[1024];
  117. char* xytzz = xyt;
  118. char* xytmaxlen = xyt + 1023;
  119. int readlen;
  120. while ((readlen = read(sockfd, xytzz, 1))) {
  121. if(*xytzz == '\n'){
  122. //printf("匹配到一个\\n\n");
  123. if(strncmp(xytzz - 3,"\r\n\r",3) == 0){
  124. *++xytzz = '\0';
  125. //printf("嗨呀,完全匹配,好开心\n");
  126. break;
  127. }
  128. }
  129. xytzz++;
  130. if(xytmaxlen == xytzz){
  131. //printf("什么吊毛协议头这么长\n");
  132. close(sockfd);
  133. return NULL;
  134. }
  135. }
  136. if(!readlen){
  137. //printf("服务器断开了连接,并未发送任何数据。\n");
  138. close(sockfd);
  139. return NULL;
  140. }
  141. //printf("%s\n--\n",xyt);
  142. char tempStart[] = "Content-Length: ";
  143. char tempEnd[] = "\n";
  144. char* xylen = strstrstr(xyt, tempStart, tempEnd);
  145. char* xyzw;
  146. if(xylen == NULL){
  147. //如果读取正文长度失败则进入分段读取模式
  148. char hexlen[8];
  149. char* hex = hexlen;
  150. do{
  151. read(sockfd, hex, 1);
  152. }while(*hex++ != '\n');
  153. *hex = '\0';
  154. int rdlen = hextoint(hexlen);
  155. if(rdlen == 0){
  156. close(sockfd);
  157. return NULL;
  158. }
  159. //rdlen++;
  160. xyzw = (char*)malloc(rdlen + 2);//把\r\n读出来
  161. read(sockfd, xyzw, rdlen + 2);//方便下面读取区块信息
  162. //xyzw[rdlen] = '\0';
  163. //读取下一块内容
  164. while(1){
  165. hex = hexlen;
  166. do{
  167. read(sockfd, hex, 1);
  168. }while(*hex++ != '\n');
  169. *hex = '\0';
  170. int chlen = hextoint(hexlen);
  171. //判断当前区块是否为0
  172. if(chlen == 0)break;
  173. rdlen += chlen;
  174. xyzw = (char*)realloc(xyzw,rdlen + 2);
  175. char* xrzz = xyzw + rdlen - chlen;
  176. read(sockfd, xrzz, chlen + 2);
  177. //xyzw[rdlen] = '\0';
  178. }
  179. xyzw[rdlen] = '\0';
  180. }else{
  181. //得到正文长度,一次性读取 申请内存
  182. int xyzwlen = atoi(xylen);
  183. free(xylen);
  184. //printf("正文共%d字节\n",xyzwlen);
  185. xyzw = (char*)malloc(xyzwlen + 1);
  186. readlen = read(sockfd, xyzw, xyzwlen);//接受网络数据
  187. xyzw[readlen] = '\0';
  188. //printf("读取了%d字节\n",readlen);
  189. }
  190. close(sockfd);
  191. return xyzw;
  192. }
  193. close(sockfd);
  194. return NULL;
  195. }
  196. char* httpget(const char* hostname, char* url){
  197. // sock句柄
  198. int sockfd;
  199. struct sockaddr_in serveraddr;
  200. //两个是同一个类型,可混用,但是会警告
  201. //int addrlen = sizeof(serveraddr);
  202. socklen_t addrlen = sizeof(serveraddr);
  203. if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
  204. //printf("创建网络连接失败---socket error!\n");
  205. return NULL;
  206. }
  207. //C4droid的GCC没有这个函数,编译会报错
  208. //bzero(&serveraddr, addrlen);
  209. //可以使用这个函数
  210. memset(&serveraddr,0,addrlen);
  211. serveraddr.sin_family = AF_INET;
  212. //端口80
  213. serveraddr.sin_port = htons(80);
  214. struct hostent* host;
  215. host = gethostbyname(hostname);
  216. if (host == NULL){
  217. //printf("无法解析域名\n");
  218. close(sockfd);
  219. return NULL;
  220. }
  221. struct in_addr ip = *((struct in_addr *)host->h_addr);
  222. //printf("ip:%s\n",inet_ntoa(ip));
  223. serveraddr.sin_addr = ip;
  224. if (connect(sockfd, (struct sockaddr*) & serveraddr, addrlen) < 0){
  225. //printf("连接到服务器失败,connect error!\n");
  226. close(sockfd);
  227. return NULL;
  228. }
  229. //因为懒,所以char[2048]
  230. //可以通过strlen获取参数长度来动态申请内存
  231. char postxyt[2048];
  232. memset(postxyt, 0, 2048);
  233. // 追加字符串(请求协议头)
  234. //个人感觉strcat函数比较低效
  235. //用char指针和strcpy函数会比较快
  236. sprintf(postxyt,"GET /%s HTTP/1.1\r\nHost: %s\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n",url,hostname);
  237. //别问,问就是 “一切皆文件”
  238. /*
  239. if (write(sockfd, postxyt, strlen(postxyt)) == -1){
  240. //printf("发送失败!错误代码:%d,错误信息:%s\n", errno, strerror(errno));
  241. close(sockfd);
  242. return NULL;
  243. }*/
  244. if (send(sockfd, postxyt, strlen(postxyt),0) == -1){
  245. printf("%d%s\n", errno, strerror(errno));
  246. close(sockfd);
  247. return NULL;
  248. }
  249. fd_set fds;
  250. struct timeval tv = { 3,0 }; //select等待3秒,3秒轮询,要非阻塞就置0
  251. //非阻塞需要循环
  252. FD_ZERO(&fds); //每次循环都要清空集合,否则不能检测描述符变化
  253. FD_SET(sockfd, &fds); //添加描述符
  254. if (select(sockfd + 1, &fds, NULL, NULL, &tv) < 1){
  255. //非阻塞时使用continue;
  256. //-1错误
  257. //0无写入数据
  258. close(sockfd);
  259. return NULL;
  260. }
  261. if (FD_ISSET(sockfd, &fds)) { //测试sock是否可读,即是否网络上有数据
  262. char xyt[1024];
  263. char* xytzz = xyt;
  264. char* xytmaxlen = xyt + 1023;
  265. int readlen;
  266. while ((readlen = read(sockfd, xytzz, 1))) {
  267. if(*xytzz == '\n'){
  268. //printf("匹配到一个\\n\n");
  269. if(strncmp(xytzz - 3,"\r\n\r",3) == 0){
  270. *++xytzz = '\0';
  271. //printf("嗨呀,完全匹配,好开心\n");
  272. break;
  273. }
  274. }
  275. xytzz++;
  276. if(xytmaxlen == xytzz){
  277. //printf("什么吊毛协议头这么长\n%s\n",xyt);
  278. close(sockfd);
  279. return NULL;
  280. }
  281. }
  282. if(!readlen){
  283. //printf("服务器断开了连接,并未发送任何数据。\n");
  284. close(sockfd);
  285. return NULL;
  286. }
  287. //printf("%s\n--\n",xyt);
  288. char tempStart[] = "Content-Length: ";
  289. char tempEnd[] = "\n";
  290. char* xylen = strstrstr(xyt, tempStart, tempEnd);
  291. char* xyzw;
  292. if(xylen == NULL){
  293. //如果读取正文长度失败则进入分段读取模式
  294. char hexlen[8];
  295. char* hex = hexlen;
  296. do{
  297. read(sockfd, hex, 1);
  298. }while(*hex++ != '\n');
  299. *hex = '\0';
  300. int rdlen = hextoint(hexlen);
  301. if(rdlen == 0){
  302. close(sockfd);
  303. return NULL;
  304. }
  305. //rdlen++;
  306. xyzw = (char*)malloc(rdlen + 2);//把\r\n读出来
  307. read(sockfd, xyzw, rdlen + 2);//方便下面读取区块信息
  308. //xyzw[rdlen] = '\0';
  309. //读取下一块内容
  310. while(1){
  311. hex = hexlen;
  312. do{
  313. read(sockfd, hex, 1);
  314. }while(*hex++ != '\n');
  315. *hex = '\0';
  316. int chlen = hextoint(hexlen);
  317. //判断当前区块是否为0
  318. if(chlen == 0)break;
  319. rdlen += chlen;
  320. xyzw = (char*)realloc(xyzw,rdlen + 2);
  321. char* xrzz = xyzw + rdlen - chlen;
  322. read(sockfd, xrzz, chlen + 2);
  323. //xyzw[rdlen] = '\0';
  324. }
  325. xyzw[rdlen] = '\0';
  326. }else{
  327. //得到正文长度,一次性读取 申请内存
  328. int xyzwlen = atoi(xylen);
  329. free(xylen);
  330. //printf("正文共%d字节\n",xyzwlen);
  331. xyzw = (char*)malloc(xyzwlen + 1);
  332. readlen = read(sockfd, xyzw, xyzwlen);//接受网络数据
  333. xyzw[readlen] = '\0';
  334. //printf("读取了%d字节\n",readlen);
  335. }
  336. close(sockfd);
  337. return xyzw;
  338. }
  339. close(sockfd);
  340. return NULL;
  341. }
  342. char* strstrstr(char* str, char* front, char* rear){
  343. if(!str || !front || !rear)return NULL;//如果你不传NULL,我至于吗
  344. char* s;
  345. char* t;
  346. while(*str) {
  347. s = str;
  348. t = front;
  349. while (*s == *t) {
  350. s++;
  351. t++;
  352. if (!*t) {
  353. str = s;
  354. char* old = str;
  355. do{
  356. s = str;
  357. t = rear;
  358. while (*s == *t) {
  359. s++;
  360. t++;
  361. if (!*t) {
  362. int charlen = str - old;
  363. char* newstr = (char*)malloc(charlen + 1);
  364. strncpy(newstr, old, charlen);
  365. //使用Visual studio编程时会警告strncpy函数存在风险,使用strncpy_s替换之
  366. //strncpy_s(newstr, charlen + 1,old, charlen);
  367. newstr[charlen] = '\0';
  368. return newstr;
  369. }
  370. }
  371. str++;
  372. }while(*str);
  373. return NULL;
  374. }
  375. }
  376. str++;
  377. }
  378. return NULL;
  379. }
  380. char* getip(char* hostname) {
  381. //不多bb,面向百度编程
  382. struct hostent* host;
  383. host = gethostbyname(hostname);
  384. if (host == NULL){
  385. perror("cannot get host by hostname");
  386. return NULL;
  387. }
  388. return inet_ntoa(*((struct in_addr *)host->h_addr));
  389. }
  390. int hextoint(char * hex){
  391. int value = 0;
  392. while (*hex){
  393. if (*hex >= 'A' && *hex <= 'F')
  394. value = (*hex - 55) + 16 * value;
  395. else if (*hex >= 'a' && *hex <= 'f')
  396. value = (*hex - 87) + 16 * value;
  397. else if (*hex >= '0' && *hex <= '9')
  398. value = (*hex - 48) + 16 * value;
  399. else{
  400. return value;
  401. }
  402. hex++;
  403. }
  404. return value;
  405. }
  406. typedef struct String
  407. {
  408. char *str;
  409. size_t len;
  410. } String;
  411. // md5
  412. typedef struct
  413. {
  414. unsigned int count[2];
  415. unsigned int state[4];
  416. unsigned char buffer[64];
  417. } MD5_CTX;
  418. #define F(x, y, z) ((x & y) | (~x & z))
  419. #define G(x, y, z) ((x & z) | (y & ~z))
  420. #define H(x, y, z) (x ^ y ^ z)
  421. #define I(x, y, z) (y ^ (x | ~z))
  422. #define ROTATE_LEFT(x, n) ((x << n) | (x >> (32 - n)))
  423. #define FF(a, b, c, d, x, s, ac) \
  424. { \
  425. a += F(b, c, d) + x + ac; \
  426. a = ROTATE_LEFT(a, s); \
  427. a += b; \
  428. }
  429. #define GG(a, b, c, d, x, s, ac) \
  430. { \
  431. a += G(b, c, d) + x + ac; \
  432. a = ROTATE_LEFT(a, s); \
  433. a += b; \
  434. }
  435. #define HH(a, b, c, d, x, s, ac) \
  436. { \
  437. a += H(b, c, d) + x + ac; \
  438. a = ROTATE_LEFT(a, s); \
  439. a += b; \
  440. }
  441. #define II(a, b, c, d, x, s, ac) \
  442. { \
  443. a += I(b, c, d) + x + ac; \
  444. a = ROTATE_LEFT(a, s); \
  445. a += b; \
  446. }
  447. #ifdef __cplusplus
  448. extern "C"
  449. {
  450. #endif
  451. void MD5Init(MD5_CTX * context);
  452. void MD5Update(MD5_CTX * context, unsigned char *input, unsigned int inputlen);
  453. void MD5Final(MD5_CTX * context, unsigned char digest[16]);
  454. void MD5Transform(unsigned int state[4], unsigned char block[64]);
  455. void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);
  456. void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);
  457. #ifdef __cplusplus
  458. }
  459. #endif
  460. // md5
  461. // base64
  462. // 填入base64自定义编码集,可用群内app生成
  463. // const char base[] =
  464. // {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+/"};
  465. static char base[65] = "Bja8hLR2f1iz/T7Ku5SVW9EUONCvg+rnQbJPy4oqel3psDkdXHAY0wxmZGIFM6ct";
  466. static union
  467. {
  468. struct
  469. {
  470. unsigned long a:6;
  471. unsigned long b:6;
  472. unsigned long c:6;
  473. unsigned long d:6;
  474. } Sdata;
  475. unsigned char c[3];
  476. } Udata;
  477. #ifdef __cplusplus
  478. extern "C"
  479. {
  480. #endif
  481. char *Encbase64(const char *orgdata); // base64加密
  482. char *Decbase64(char *orgdata); // base64解密
  483. char *toHEX(const char *string); // 转16进制
  484. void setbase(const char b[65]); // 设置base编码集
  485. char *itoa(int num, char *str, int radix);
  486. #ifdef __cplusplus
  487. }
  488. #endif
  489. #ifdef __cplusplus
  490. extern "C"
  491. {
  492. #endif
  493. // RC4
  494. void swap(unsigned char *s1, unsigned char *s2);
  495. void re_S(unsigned char *S);
  496. void re_T(unsigned char *T, const char *key);
  497. void re_Sbox(unsigned char *S, unsigned char *T);
  498. void re_RC4(unsigned char *S, const char *key);
  499. String RC4(const String data, const char *key);
  500. #ifdef __cplusplus
  501. }
  502. #endif
  503. // base代码
  504. void setbase(const char b[65])
  505. {
  506. strncpy(base, b, 64);
  507. }
  508. char *itoa(int num, char *str, int radix)
  509. {
  510. char index[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 索引表
  511. unsigned unum; // 存放要转换的整数的绝对值,转换的整数可能是负数
  512. int i = 0, j, k; // i用来指示设置字符串相应位,转换之后i其实就是字符串的长度;转换后顺序是逆序的,有正负的情况,k用来指示调整顺序的开始位置;j用来指示调整顺序时的交换。
  513. // 获取要转换的整数的绝对值
  514. if (radix == 10 && num < 0) // 要转换成十进制数并且是负数
  515. {
  516. unum = (unsigned)-num; // 将num的绝对值赋给unum
  517. str[i++] = '-'; // 在字符串最前面设置为'-'号,并且索引加1
  518. }
  519. else
  520. unum = (unsigned)num; // 若是num为正,直接赋值给unum
  521. // 转换部分,注意转换后是逆序的
  522. do
  523. {
  524. str[i++] = index[unum % (unsigned)radix]; // 取unum的最后一位,并设置为str对应位,指示索引加1
  525. unum /= radix; // unum去掉最后一位
  526. }
  527. while (unum); // 直至unum为0退出循环
  528. str[i] = '\0'; // 在字符串最后添加'\0'字符,c语言字符串以'\0'结束。
  529. // 将顺序调整过来
  530. if (str[0] == '-')
  531. k = 1; // 如果是负数,符号不用调整,从符号后面开始调整
  532. else
  533. k = 0; // 不是负数,全部都要调整
  534. char temp; // 临时变量,交换两个值时用到
  535. for (j = k; j <= (i - 1) / 2; j++) // 头尾一一对称交换,i其实就是字符串的长度,索引最大值比长度少1
  536. {
  537. temp = str[j]; // 头部赋值给临时变量
  538. str[j] = str[i - 1 + k - j]; // 尾部赋值给头部
  539. str[i - 1 + k - j] = temp; // 将临时变量的值(其实就是之前的头部值)赋给尾部
  540. }
  541. return str; // 返回转换后的字符串
  542. }
  543. char *toHEX(const char *string)
  544. {
  545. char chs;
  546. char *ret;
  547. char *str;
  548. if (!string || (ret = str = (char *)malloc(strlen(string) * 2 + 1)) == NULL)
  549. return NULL;
  550. while (*string)
  551. {
  552. chs = (*string & 0XF0) >> 4;
  553. if (chs > 9)
  554. *str = chs - 10 + 'A'; // chs - 10 + 'A'
  555. else
  556. *str = chs + '0';
  557. str++;
  558. chs = *string & 0X0F;
  559. if (chs > 9)
  560. *str = chs - 10 + 'A'; // chs - 10 + 'A'
  561. else
  562. *str = chs + '0';
  563. str++;
  564. string++;
  565. }
  566. *str = '\0';
  567. return ret;
  568. }
  569. char *Encbase64(const char *orgdata)
  570. {
  571. const char *p = NULL;
  572. char *ret = NULL;
  573. int tlen = 0;
  574. if (orgdata == NULL)
  575. return NULL;
  576. unsigned long orglen = strlen(orgdata);
  577. tlen = orglen / 3;
  578. if (tlen % 3 != 0)
  579. tlen++;
  580. tlen = tlen * 4;
  581. if ((ret = (char *)malloc(tlen + 1)) == NULL)
  582. return NULL;
  583. memset(ret, 0, tlen + 1);
  584. p = orgdata;
  585. tlen = orglen;
  586. int i = 0, j = 0;
  587. while (tlen > 0)
  588. {
  589. Udata.c[0] = Udata.c[1] = Udata.c[2] = 0;
  590. for (i = 0; i < 3; i++)
  591. {
  592. if (tlen < 1)
  593. break;
  594. Udata.c[i] = (char)*p;
  595. tlen--;
  596. p++;
  597. }
  598. if (i == 0)
  599. break;
  600. switch (i)
  601. {
  602. case 1:
  603. /* ret[j++]=base[Udata.Sdata.d]; ret[j++]=base[Udata.Sdata.c];
  604. ret[j++]=base[64]; ret[j++]=base[64]; */
  605. ret[j++] = base[Udata.c[0] >> 2];
  606. ret[j++] = base[((Udata.c[0] & 0x03) << 4) | ((Udata.c[1] & 0xf0) >> 4)];
  607. ret[j++] = base[64];
  608. ret[j++] = base[64];
  609. break;
  610. case 2:
  611. /* ret[j++]=base[Udata.Sdata.d]; ret[j++]=base[Udata.Sdata.c];
  612. ret[j++]=base[Udata.Sdata.b]; ret[j++]=base[64]; */
  613. ret[j++] = base[Udata.c[0] >> 2];
  614. ret[j++] = base[((Udata.c[0] & 0x03) << 4) | ((Udata.c[1] & 0xf0) >> 4)];
  615. ret[j++] = base[((Udata.c[1] & 0x0f) << 2) | ((Udata.c[2] & 0xc0) >> 6)];
  616. ret[j++] = base[64];
  617. break;
  618. case 3:
  619. /* ret[j++]=base[Udata.Sdata.d]; ret[j++]=base[Udata.Sdata.c];
  620. ret[j++]=base[Udata.Sdata.b]; ret[j++]=base[Udata.Sdata.a]; */
  621. ret[j++] = base[Udata.c[0] >> 2];
  622. ret[j++] = base[((Udata.c[0] & 0x03) << 4) | ((Udata.c[1] & 0xf0) >> 4)];
  623. ret[j++] = base[((Udata.c[1] & 0x0f) << 2) | ((Udata.c[2] & 0xc0) >> 6)];
  624. ret[j++] = base[Udata.c[2] & 0x3f];
  625. break;
  626. default:
  627. break;
  628. }
  629. }
  630. ret[j] = '\0';
  631. return ret;
  632. }
  633. char *Decbase64(char *orgdata)
  634. {
  635. char *p, *ret;
  636. int len;
  637. unsigned long orglen;
  638. char ch[4] = { 0 };
  639. char *pos[4];
  640. int offset[4];
  641. if (orgdata == NULL)
  642. return NULL;
  643. orglen = strlen(orgdata);
  644. len = orglen * 3 / 4;
  645. if ((ret = (char *)malloc(len + 1)) == NULL)
  646. return NULL;
  647. p = orgdata;
  648. len = orglen;
  649. int j = 0;
  650. while (len > 0)
  651. {
  652. int i = 0;
  653. while (i < 4)
  654. {
  655. if (len > 0)
  656. {
  657. ch[i] = *p;
  658. p++;
  659. len--;
  660. if ((pos[i] = (char *)strchr(base, ch[i])) == NULL)
  661. {
  662. if (ch[i] == '=')
  663. {
  664. offset[i] = 0;
  665. i++;
  666. continue;
  667. // break;
  668. }
  669. free(ret);
  670. return NULL;
  671. }
  672. offset[i] = pos[i] - base;
  673. }
  674. i++;
  675. }
  676. if (ch[0] == '=' || ch[1] == '=' || (ch[2] == '=' && ch[3] != '='))
  677. {
  678. free(ret);
  679. return NULL;
  680. }
  681. ret[j++] = (unsigned char)(offset[0] << 2 | offset[1] >> 4);
  682. ret[j++] = offset[2] == 64 ? '\0' : (unsigned char)(offset[1] << 4 | offset[2] >> 2);
  683. ret[j++] = offset[3] == 64 ? '\0' : (unsigned char)((offset[2] << 6 & 0xc0) | offset[3]);
  684. }
  685. ret[j] = '\0';
  686. return ret;
  687. }
  688. // md5代码区
  689. unsigned char PADDING[] = { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  690. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  691. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  692. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  693. };
  694. // 定制md5
  695. void MD5Init(MD5_CTX * context)
  696. {
  697. context->count[0] = 0;
  698. context->count[1] = 0;
  699. context->state[0] = 0x67452301;
  700. context->state[1] = 0xEFCDAB89;
  701. context->state[2] = 0x98BADCFE;
  702. context->state[3] = 0x10325476;
  703. }
  704. void MD5Update(MD5_CTX * context, unsigned char *input, unsigned int inputlen)
  705. {
  706. unsigned int i = 0, index = 0, partlen = 0;
  707. index = (context->count[0] >> 3) & 0x3F;
  708. partlen = 64 - index;
  709. context->count[0] += inputlen << 3;
  710. if (context->count[0] < (inputlen << 3))
  711. context->count[1]++;
  712. context->count[1] += inputlen >> 29;
  713. if (inputlen >= partlen)
  714. {
  715. memcpy(&context->buffer[index], input, partlen);
  716. MD5Transform(context->state, context->buffer);
  717. for (i = partlen; i + 64 <= inputlen; i += 64)
  718. MD5Transform(context->state, &input[i]);
  719. index = 0;
  720. }
  721. else
  722. {
  723. i = 0;
  724. }
  725. memcpy(&context->buffer[index], &input[i], inputlen - i);
  726. }
  727. void MD5Final(MD5_CTX * context, unsigned char digest[16])
  728. {
  729. unsigned int index = 0, padlen = 0;
  730. unsigned char bits[8];
  731. index = (context->count[0] >> 3) & 0x3F;
  732. padlen = (index < 56) ? (56 - index) : (120 - index);
  733. MD5Encode(bits, context->count, 8);
  734. MD5Update(context, PADDING, padlen);
  735. MD5Update(context, bits, 8);
  736. MD5Encode(digest, context->state, 16);
  737. }
  738. void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len)
  739. {
  740. unsigned int i = 0, j = 0;
  741. while (j < len)
  742. {
  743. output[j] = input[i] & 0xFF;
  744. output[j + 1] = (input[i] >> 8) & 0xFF;
  745. output[j + 2] = (input[i] >> 16) & 0xFF;
  746. output[j + 3] = (input[i] >> 24) & 0xFF;
  747. i++;
  748. j += 4;
  749. }
  750. }
  751. void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len)
  752. {
  753. unsigned int i = 0, j = 0;
  754. while (j < len)
  755. {
  756. output[i] = (input[j]) | (input[j + 1] << 8) | (input[j + 2] << 16) | (input[j + 3] << 24);
  757. i++;
  758. j += 4;
  759. }
  760. }
  761. void MD5Transform(unsigned int state[4], unsigned char block[64])
  762. {
  763. unsigned int a = state[0];
  764. unsigned int b = state[1];
  765. unsigned int c = state[2];
  766. unsigned int d = state[3];
  767. unsigned int x[64];
  768. MD5Decode(x, block, 64);
  769. FF(a, b, c, d, x[0], 7, 0xd76aa478);
  770. FF(d, a, b, c, x[1], 12, 0xe8c7b756);
  771. FF(c, d, a, b, x[2], 17, 0x242070db);
  772. FF(b, c, d, a, x[3], 22, 0xc1bdceee);
  773. FF(a, b, c, d, x[4], 7, 0xf57c0faf);
  774. FF(d, a, b, c, x[5], 12, 0x4787c62a);
  775. FF(c, d, a, b, x[6], 17, 0xa8304613);
  776. FF(b, c, d, a, x[7], 22, 0xfd469501);
  777. FF(a, b, c, d, x[8], 7, 0x698098d8);
  778. FF(d, a, b, c, x[9], 12, 0x8b44f7af);
  779. FF(c, d, a, b, x[10], 17, 0xffff5bb1);
  780. FF(b, c, d, a, x[11], 22, 0x895cd7be);
  781. FF(a, b, c, d, x[12], 7, 0x6b901122);
  782. FF(d, a, b, c, x[13], 12, 0xfd987193);
  783. FF(c, d, a, b, x[14], 17, 0xa679438e);
  784. FF(b, c, d, a, x[15], 22, 0x49b40821);
  785. GG(a, b, c, d, x[1], 5, 0xf61e2562);
  786. GG(d, a, b, c, x[6], 9, 0xc040b340);
  787. GG(c, d, a, b, x[11], 14, 0x265e5a51);
  788. GG(b, c, d, a, x[0], 20, 0xe9b6c7aa);
  789. GG(a, b, c, d, x[5], 5, 0xd62f105d);
  790. GG(d, a, b, c, x[10], 9, 0x2441453);
  791. GG(c, d, a, b, x[15], 14, 0xd8a1e681);
  792. GG(b, c, d, a, x[4], 20, 0xe7d3fbc8);
  793. GG(a, b, c, d, x[9], 5, 0x21e1cde6);
  794. GG(d, a, b, c, x[14], 9, 0xc33707d6);
  795. GG(c, d, a, b, x[3], 14, 0xf4d50d87);
  796. GG(b, c, d, a, x[8], 20, 0x455a14ed);
  797. GG(a, b, c, d, x[13], 5, 0xa9e3e905);
  798. GG(d, a, b, c, x[2], 9, 0xfcefa3f8);
  799. GG(c, d, a, b, x[7], 14, 0x676f02d9);
  800. GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);
  801. HH(a, b, c, d, x[5], 4, 0xfffa3942);
  802. HH(d, a, b, c, x[8], 11, 0x8771f681);
  803. HH(c, d, a, b, x[11], 16, 0x6d9d6122);
  804. HH(b, c, d, a, x[14], 23, 0xfde5380c);
  805. HH(a, b, c, d, x[1], 4, 0xa4beea44);
  806. HH(d, a, b, c, x[4], 11, 0x4bdecfa9);
  807. HH(c, d, a, b, x[7], 16, 0xf6bb4b60);
  808. HH(b, c, d, a, x[10], 23, 0xbebfbc70);
  809. HH(a, b, c, d, x[13], 4, 0x289b7ec6);
  810. HH(d, a, b, c, x[0], 11, 0xeaa127fa);
  811. HH(c, d, a, b, x[3], 16, 0xd4ef3085);
  812. HH(b, c, d, a, x[6], 23, 0x4881d05);
  813. HH(a, b, c, d, x[9], 4, 0xd9d4d039);
  814. HH(d, a, b, c, x[12], 11, 0xe6db99e5);
  815. HH(c, d, a, b, x[15], 16, 0x1fa27cf8);
  816. HH(b, c, d, a, x[2], 23, 0xc4ac5665);
  817. II(a, b, c, d, x[0], 6, 0xf4292244);
  818. II(d, a, b, c, x[7], 10, 0x432aff97);
  819. II(c, d, a, b, x[14], 15, 0xab9423a7);
  820. II(b, c, d, a, x[5], 21, 0xfc93a039);
  821. II(a, b, c, d, x[12], 6, 0x655b59c3);
  822. II(d, a, b, c, x[3], 10, 0x8f0ccc92);
  823. II(c, d, a, b, x[10], 15, 0xffeff47d);
  824. II(b, c, d, a, x[1], 21, 0x85845dd1);
  825. II(a, b, c, d, x[8], 6, 0x6fa87e4f);
  826. II(d, a, b, c, x[15], 10, 0xfe2ce6e0);
  827. II(c, d, a, b, x[6], 15, 0xa3014314);
  828. II(b, c, d, a, x[13], 21, 0x4e0811a1);
  829. II(a, b, c, d, x[4], 6, 0xf7537e82);
  830. II(d, a, b, c, x[11], 10, 0xbd3af235);
  831. II(c, d, a, b, x[2], 15, 0x2ad7d2bb);
  832. II(b, c, d, a, x[9], 21, 0xeb86d391);
  833. state[0] += a;
  834. state[1] += b;
  835. state[2] += c;
  836. state[3] += d;
  837. }
  838. // rc4加解密
  839. // 一键加密
  840. char *yjjm(const char *data);
  841. // 校验函数
  842. char *yjjm(const char *data)
  843. {
  844. char *mw;
  845. data = Encbase64(data);
  846. mw = toHEX(data);
  847. //free(data);
  848. return mw;
  849. }
  850. /* 验证函数结束 */