Question: C语言实现DES加密与解密算法

引用 1 楼 hemowolf 的回复:  #include "stdafx.h"  #include "cstring"  #include "stdio.h"  #include "time.h"  #include "stdlib.h"   #define PLAIN_FILE_OPEN_ERROR -1  #define KEY_FILE_OPEN_ERROR -2  #define CIPHER_FILE_OPEN_ERROR -3  #define OK 1;   int IP_Table[64] = { 57,49,41,33,25,17,9,1,  	59,51,43,35,27,19,11,3,  	61,53,45,37,29,21,13,5,  	63,55,47,39,31,23,15,7,  	56,48,40,32,24,16,8,0,  	58,50,42,34,26,18,10,2,  	60,52,44,36,28,20,12,4,  	62,54,46,38,30,22,14,6};   int IP_1_Table[64] = {39,7,47,15,55,23,63,31,  	38,6,46,14,54,22,62,30,  	37,5,45,13,53,21,61,29,  	36,4,44,12,52,20,60,28,  	35,3,43,11,51,19,59,27,  	34,2,42,10,50,18,58,26,  	33,1,41,9,49,17,57,25,  	32,0,40,8,48,16,56,24};    int E_Table[48] = {31, 0, 1, 2, 3, 4,  	3, 4, 5, 6, 7, 8,  	7, 8,9,10,11,12,  	11,12,13,14,15,16,  	15,16,17,18,19,20,  	19,20,21,22,23,24,  	23,24,25,26,27,28,  	27,28,29,30,31, 0};   int P_Table[32] = {15,6,19,20,28,11,27,16,  	0,14,22,25,4,17,30,9,  	1,7,23,13,31,26,2,8,  	18,12,29,5,21,10,3,24};   int S[8][4][16] =  	/* S1 */  {{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},  {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},  {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},  {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},  /* S2 */  {{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},  {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},  {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},  {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},  /* S3 */  {{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},  {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},  {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},  {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},  /* S4 */  {{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},  {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},  {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},  {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},  /* S5 */  {{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},  {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},  {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},  {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},  /* S6 */  {{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},  {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},  {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},  {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},  /* S7 */  {{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},  {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},  {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},  {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},  /* S8 */  {{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},  {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},  {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},  {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};    int PC_1[56] = {56,48,40,32,24,16,8,  	0,57,49,41,33,25,17,  	9,1,58,50,42,34,26,  	18,10,2,59,51,43,35,  	62,54,46,38,30,22,14,  	6,61,53,45,37,29,21,  	13,5,60,52,44,36,28,  	20,12,4,27,19,11,3};   int PC_2[48] = {13,16,10,23,0,4,2,27,  	14,5,20,9,22,18,11,3,  	25,7,15,6,26,19,12,1,  	40,51,30,36,46,54,29,39,  	50,44,32,46,43,48,38,55,  	33,52,45,41,49,35,28,31};   int MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};  int ByteToBit(char ch,char bit[8]);  int BitToByte(char bit[8],char *ch);  int Char8ToBit64(char ch[8],char bit[64]);  int Bit64ToChar8(char bit[64],char ch[8]);  int DES_MakeSubKeys(char key[64],char subKeys[16][48]);  int DES_PC1_Transform(char key[64], char tempbts[56]);  int DES_PC2_Transform(char key[56], char tempbts[48]);  int DES_ROL(char data[56], int time);  int DES_IP_Transform(char data[64]);  int DES_IP_1_Transform(char data[64]);  int DES_E_Transform(char data[48]);  int DES_P_Transform(char data[32]);  int DES_SBOX(char data[48]);  int DES_XOR(char R[48], char L[48],int count);  int DES_Swap(char left[32],char right[32]);  int DES_EncryptBlock(char plainBlock[8], char subKeys[16][48], char cipherBlock[8]);  int DES_DecryptBlock(char cipherBlock[8], char subKeys[16][48], char plainBlock[8]);  int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);  int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile);   int ByteToBit(char ch, char bit[8]){  	int cnt;  	for(cnt = 0;cnt < 8; cnt++){  		*(bit+cnt) = (ch>>cnt)&1;  	}  	return 0;  }   int BitToByte(char bit[8],char *ch){  	int cnt;  	for(cnt = 0;cnt < 8; cnt++){  		*ch |= *(bit + cnt)<<cnt;  	}  	return 0;  }   int Char8ToBit64(char ch[8],char bit[64]){  	int cnt;  	for(cnt = 0; cnt < 8; cnt++){  		ByteToBit(*(ch+cnt),bit+(cnt<<3));  	}  	return 0;  }    int Bit64ToChar8(char bit[64],char ch[8]){  	int cnt;  	memset(ch,0,8);  	for(cnt = 0; cnt < 8; cnt++){  		BitToByte(bit+(cnt<<3),ch+cnt);  	}  	return 0;  }   int DES_MakeSubKeys(char key[64],char subKeys[16][48]){  	char temp[56];  	int cnt;  	DES_PC1_Transform(key,temp); 	for(cnt = 0; cnt < 16; cnt++){ 		DES_ROL(temp,MOVE_TIMES[cnt]); 		DES_PC2_Transform(temp,subKeys[cnt]); 	}  	return 0;  }   int DES_PC1_Transform(char key[64], char tempbts[56]){  	int cnt;  	for(cnt = 0; cnt < 56; cnt++){  		tempbts[cnt] = key[PC_1[cnt]];  	}  	return 0;  }   int DES_PC2_Transform(char key[56], char tempbts[48]){  	int cnt;  	for(cnt = 0; cnt < 48; cnt++){  		tempbts[cnt] = key[PC_2[cnt]];  	}  	return 0;  }   int DES_ROL(char data[56], int time){  	char temp[56];  	memcpy(temp,data,time);  	memcpy(temp+time,data+28,time);  	memcpy(data,data+time,28-time);  	memcpy(data+28-time,temp,time);  	memcpy(data+28,data+28+time,28-time);  	memcpy(data+56-time,temp+time,time);  	return 0;  }   int DES_IP_Transform(char data[64]){  	int cnt;  	char temp[64];  	for(cnt = 0; cnt < 64; cnt++){  		temp[cnt] = data[IP_Table[cnt]];  	}  	memcpy(data,temp,64);  	return 0;  }   int DES_IP_1_Transform(char data[64]){  	int cnt;  	char temp[64];  	for(cnt = 0; cnt < 64; cnt++){  		temp[cnt] = data[IP_1_Table[cnt]];  	}  	memcpy(data,temp,64);  	return 0;  }   int DES_E_Transform(char data[48]){  	int cnt;  	char temp[48];  	for(cnt = 0; cnt < 48; cnt++){  		temp[cnt] = data[E_Table[cnt]];  	}  	memcpy(data,temp,48);  	return 0;  }   int DES_P_Transform(char data[32]){  	int cnt;  	char temp[32];  	for(cnt = 0; cnt < 32; cnt++){  		temp[cnt] = data[P_Table[cnt]];  	}  	memcpy(data,temp,32);  	return 0;  }   int DES_XOR(char R[48], char L[48] ,int count){  	int cnt;  	for(cnt = 0; cnt < count; cnt++){  		R[cnt] ^= L[cnt];  	}  	return 0;  }   int DES_SBOX(char data[48]){  	int cnt;  	int line,row,output;  	int cur1,cur2;  	for(cnt = 0; cnt < 8; cnt++){  		cur1 = cnt*6;  		cur2 = cnt<<2;   		line = (data[cur1]<<1) + data[cur1+5];  		row = (data[cur1+1]<<3) + (data[cur1+2]<<2)  			+ (data[cur1+3]<<1) + data[cur1+4];  		output = S[cnt][line][row];   		data[cur2] = (output&0X08)>>3;  		data[cur2+1] = (output&0X04)>>2;  		data[cur2+2] = (output&0X02)>>1;  		data[cur2+3] = output&0x01;  	}  	return 0;  }   int DES_Swap(char left[32], char right[32]){  	char temp[32];  	memcpy(temp,left,32);  	memcpy(left,right,32);  	memcpy(right,temp,32);  	return 0;  }   int DES_EncryptBlock(char plainBlock[8], char subKeys[16][48], char cipherBlock[8]){  	char plainBits[64];  	char copyRight[48];  	int cnt;  	Char8ToBit64(plainBlock,plainBits);   	DES_IP_Transform(plainBits);  	for(cnt = 0; cnt < 16; cnt++){  		memcpy(copyRight,plainBits+32,32);  		DES_E_Transform(copyRight);  		DES_XOR(copyRight,subKeys[cnt],48);  		DES_SBOX(copyRight);  		DES_P_Transform(copyRight);  		DES_XOR(plainBits,copyRight,32);  		if(cnt != 15){  			DES_Swap(plainBits,plainBits+32);  		}  	}  	DES_IP_1_Transform(plainBits);  	Bit64ToChar8(plainBits,cipherBlock);  	return 0;  }    不明白为啥会有 ByteToBit 这样的函数，默认内存中不就是存放的bit

引用 17 楼 sinat_27382047 的回复:[quote=引用 1 楼 hemowolf 的回复:]   #include "stdafx.h"  #include "cstring"  #include "stdio.h"  #include "time.h"  #include "stdlib.h"   #define PLAIN_FILE_OPEN_ERROR -1  #define KEY_FILE_OPEN_ERROR -2  #define CIPHER_FILE_OPEN_ERROR -3  #define OK 1;   int IP_Table[64] = { 57,49,41,33,25,17,9,1,  	59,51,43,35,27,19,11,3,  	61,53,45,37,29,21,13,5,  	63,55,47,39,31,23,15,7,  	56,48,40,32,24,16,8,0,  	58,50,42,34,26,18,10,2,  	60,52,44,36,28,20,12,4,  	62,54,46,38,30,22,14,6};   int IP_1_Table[64] = {39,7,47,15,55,23,63,31,  	38,6,46,14,54,22,62,30,  	37,5,45,13,53,21,61,29,  	36,4,44,12,52,20,60,28,  	35,3,43,11,51,19,59,27,  	34,2,42,10,50,18,58,26,  	33,1,41,9,49,17,57,25,  	32,0,40,8,48,16,56,24};    int E_Table[48] = {31, 0, 1, 2, 3, 4,  	3, 4, 5, 6, 7, 8,  	7, 8,9,10,11,12,  	11,12,13,14,15,16,  	15,16,17,18,19,20,  	19,20,21,22,23,24,  	23,24,25,26,27,28,  	27,28,29,30,31, 0};   int P_Table[32] = {15,6,19,20,28,11,27,16,  	0,14,22,25,4,17,30,9,  	1,7,23,13,31,26,2,8,  	18,12,29,5,21,10,3,24};   int S[8][4][16] =  	/* S1 */  {{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},  {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},  {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},  {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},  /* S2 */  {{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},  {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},  {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},  {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},  /* S3 */  {{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},  {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},  {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},  {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},  /* S4 */  {{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},  {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},  {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},  {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},  /* S5 */  {{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},  {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},  {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},  {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},  /* S6 */  {{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},  {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},  {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},  {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},  /* S7 */  {{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},  {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},  {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},  {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},  /* S8 */  {{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},  {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},  {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},  {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};    int PC_1[56] = {56,48,40,32,24,16,8,  	0,57,49,41,33,25,17,  	9,1,58,50,42,34,26,  	18,10,2,59,51,43,35,  	62,54,46,38,30,22,14,  	6,61,53,45,37,29,21,  	13,5,60,52,44,36,28,  	20,12,4,27,19,11,3};   int PC_2[48] = {13,16,10,23,0,4,2,27,  	14,5,20,9,22,18,11,3,  	25,7,15,6,26,19,12,1,  	40,51,30,36,46,54,29,39,  	50,44,32,46,43,48,38,55,  	33,52,45,41,49,35,28,31};   int MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};  int ByteToBit(char ch,char bit[8]);  int BitToByte(char bit[8],char *ch);  int Char8ToBit64(char ch[8],char bit[64]);  int Bit64ToChar8(char bit[64],char ch[8]);  int DES_MakeSubKeys(char key[64],char subKeys[16][48]);  int DES_PC1_Transform(char key[64], char tempbts[56]);  int DES_PC2_Transform(char key[56], char tempbts[48]);  int DES_ROL(char data[56], int time);  int DES_IP_Transform(char data[64]);  int DES_IP_1_Transform(char data[64]);  int DES_E_Transform(char data[48]);  int DES_P_Transform(char data[32]);  int DES_SBOX(char data[48]);  int DES_XOR(char R[48], char L[48],int count);  int DES_Swap(char left[32],char right[32]);  int DES_EncryptBlock(char plainBlock[8], char subKeys[16][48], char cipherBlock[8]);  int DES_DecryptBlock(char cipherBlock[8], char subKeys[16][48], char plainBlock[8]);  int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);  int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile);   int ByteToBit(char ch, char bit[8]){  	int cnt;  	for(cnt = 0;cnt < 8; cnt++){  		*(bit+cnt) = (ch>>cnt)&1;  	}  	return 0;  }   int BitToByte(char bit[8],char *ch){  	int cnt;  	for(cnt = 0;cnt < 8; cnt++){  		*ch |= *(bit + cnt)<<cnt;  	}  	return 0;  }   int Char8ToBit64(char ch[8],char bit[64]){  	int cnt;  	for(cnt = 0; cnt < 8; cnt++){  		ByteToBit(*(ch+cnt),bit+(cnt<<3));  	}  	return 0;  }    int Bit64ToChar8(char bit[64],char ch[8]){  	int cnt;  	memset(ch,0,8);  	for(cnt = 0; cnt < 8; cnt++){  		BitToByte(bit+(cnt<<3),ch+cnt);  	}  	return 0;  }   int DES_MakeSubKeys(char key[64],char subKeys[16][48]){  	char temp[56];  	int cnt;  	DES_PC1_Transform(key,temp); 	for(cnt = 0; cnt < 16; cnt++){ 		DES_ROL(temp,MOVE_TIMES[cnt]); 		DES_PC2_Transform(temp,subKeys[cnt]); 	}  	return 0;  }   int DES_PC1_Transform(char key[64], char tempbts[56]){  	int cnt;  	for(cnt = 0; cnt < 56; cnt++){  		tempbts[cnt] = key[PC_1[cnt]];  	}  	return 0;  }   int DES_PC2_Transform(char key[56], char tempbts[48]){  	int cnt;  	for(cnt = 0; cnt < 48; cnt++){  		tempbts[cnt] = key[PC_2[cnt]];  	}  	return 0;  }   int DES_ROL(char data[56], int time){  	char temp[56];  	memcpy(temp,data,time);  	memcpy(temp+time,data+28,time);  	memcpy(data,data+time,28-time);  	memcpy(data+28-time,temp,time);  	memcpy(data+28,data+28+time,28-time);  	memcpy(data+56-time,temp+time,time);  	return 0;  }   int DES_IP_Transform(char data[64]){  	int cnt;  	char temp[64];  	for(cnt = 0; cnt < 64; cnt++){  		temp[cnt] = data[IP_Table[cnt]];  	}  	memcpy(data,temp,64);  	return 0;  }   int DES_IP_1_Transform(char data[64]){  	int cnt;  	char temp[64];  	for(cnt = 0; cnt < 64; cnt++){  		temp[cnt] = data[IP_1_Table[cnt]];  	}  	memcpy(data,temp,64);  	return 0;  }   int DES_E_Transform(char data[48]){  	int cnt;  	char temp[48];  	for(cnt = 0; cnt < 48; cnt++){  		temp[cnt] = data[E_Table[cnt]];  	}  	memcpy(data,temp,48);  	return 0;  }   int DES_P_Transform(char data[32]){  	int cnt;  	char temp[32];  	for(cnt = 0; cnt < 32; cnt++){  		temp[cnt] = data[P_Table[cnt]];  	}  	memcpy(data,temp,32);  	return 0;  }   int DES_XOR(char R[48], char L[48] ,int count){  	int cnt;  	for(cnt = 0; cnt < count; cnt++){  		R[cnt] ^= L[cnt];  	}  	return 0;  }   int DES_SBOX(char data[48]){  	int cnt;  	int line,row,output;  	int cur1,cur2;  	for(cnt = 0; cnt < 8; cnt++){  		cur1 = cnt*6;  		cur2 = cnt<<2;   		line = (data[cur1]<<1) + data[cur1+5];  		row = (data[cur1+1]<<3) + (data[cur1+2]<<2)  			+ (data[cur1+3]<<1) + data[cur1+4];  		output = S[cnt][line][row];   		data[cur2] = (output&0X08)>>3;  		data[cur2+1] = (output&0X04)>>2;  		data[cur2+2] = (output&0X02)>>1;  		data[cur2+3] = output&0x01;  	}  	return 0;  }   int DES_Swap(char left[32], char right[32]){  	char temp[32];  	memcpy(temp,left,32);  	memcpy(left,right,32);  	memcpy(right,temp,32);  	return 0;  }   int DES_EncryptBlock(char plainBlock[8], char subKeys[16][48], char cipherBlock[8]){  	char plainBits[64];  	char copyRight[48];  	int cnt;  	Char8ToBit64(plainBlock,plainBits);   	DES_IP_Transform(plainBits);  	for(cnt = 0; cnt < 16; cnt++){  		memcpy(copyRight,plainBits+32,32);  		DES_E_Transform(copyRight);  		DES_XOR(copyRight,subKeys[cnt],48);  		DES_SBOX(copyRight);  		DES_P_Transform(copyRight);  		DES_XOR(plainBits,copyRight,32);  		if(cnt != 15){  			DES_Swap(plainBits,plainBits+32);  		}  	}  	DES_IP_1_Transform(plainBits);  	Bit64ToChar8(plainBits,cipherBlock);  	return 0;  }  楼主，你的置换码表是不是不对，网上找了好多，都是和你不一样的一个样子 你的 int IP_Table[64] = { 57,49,41,33,25,17,9,1,      59,51,43,35,27,19,11,3,      61,53,45,37,29,21,13,5,      63,55,47,39,31,23,15,7,      56,48,40,32,24,16,8,0,      58,50,42,34,26,18,10,2,      60,52,44,36,28,20,12,4,      62,54,46,38,30,22,14,6};   人家的 int IP_Table[64] = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17,  9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 };  每位都差1[/quote] 可能因为他们的算法里都有-1操作，所以你们的置换码表不一样

引用 1 楼 hemowolf 的回复:  #include "stdafx.h"  #include "cstring"  #include "stdio.h"  #include "time.h"  #include "stdlib.h"   #define PLAIN_FILE_OPEN_ERROR -1  #define KEY_FILE_OPEN_ERROR -2  #define CIPHER_FILE_OPEN_ERROR -3  #define OK 1;   int IP_Table[64] = { 57,49,41,33,25,17,9,1,  	59,51,43,35,27,19,11,3,  	61,53,45,37,29,21,13,5,  	63,55,47,39,31,23,15,7,  	56,48,40,32,24,16,8,0,  	58,50,42,34,26,18,10,2,  	60,52,44,36,28,20,12,4,  	62,54,46,38,30,22,14,6};   int IP_1_Table[64] = {39,7,47,15,55,23,63,31,  	38,6,46,14,54,22,62,30,  	37,5,45,13,53,21,61,29,  	36,4,44,12,52,20,60,28,  	35,3,43,11,51,19,59,27,  	34,2,42,10,50,18,58,26,  	33,1,41,9,49,17,57,25,  	32,0,40,8,48,16,56,24};    int E_Table[48] = {31, 0, 1, 2, 3, 4,  	3, 4, 5, 6, 7, 8,  	7, 8,9,10,11,12,  	11,12,13,14,15,16,  	15,16,17,18,19,20,  	19,20,21,22,23,24,  	23,24,25,26,27,28,  	27,28,29,30,31, 0};   int P_Table[32] = {15,6,19,20,28,11,27,16,  	0,14,22,25,4,17,30,9,  	1,7,23,13,31,26,2,8,  	18,12,29,5,21,10,3,24};   int S[8][4][16] =  	/* S1 */  {{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},  {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},  {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},  {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},  /* S2 */  {{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},  {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},  {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},  {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},  /* S3 */  {{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},  {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},  {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},  {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},  /* S4 */  {{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},  {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},  {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},  {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},  /* S5 */  {{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},  {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},  {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},  {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},  /* S6 */  {{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},  {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},  {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},  {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},  /* S7 */  {{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},  {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},  {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},  {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},  /* S8 */  {{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},  {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},  {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},  {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};    int PC_1[56] = {56,48,40,32,24,16,8,  	0,57,49,41,33,25,17,  	9,1,58,50,42,34,26,  	18,10,2,59,51,43,35,  	62,54,46,38,30,22,14,  	6,61,53,45,37,29,21,  	13,5,60,52,44,36,28,  	20,12,4,27,19,11,3};   int PC_2[48] = {13,16,10,23,0,4,2,27,  	14,5,20,9,22,18,11,3,  	25,7,15,6,26,19,12,1,  	40,51,30,36,46,54,29,39,  	50,44,32,46,43,48,38,55,  	33,52,45,41,49,35,28,31};   int MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};  int ByteToBit(char ch,char bit[8]);  int BitToByte(char bit[8],char *ch);  int Char8ToBit64(char ch[8],char bit[64]);  int Bit64ToChar8(char bit[64],char ch[8]);  int DES_MakeSubKeys(char key[64],char subKeys[16][48]);  int DES_PC1_Transform(char key[64], char tempbts[56]);  int DES_PC2_Transform(char key[56], char tempbts[48]);  int DES_ROL(char data[56], int time);  int DES_IP_Transform(char data[64]);  int DES_IP_1_Transform(char data[64]);  int DES_E_Transform(char data[48]);  int DES_P_Transform(char data[32]);  int DES_SBOX(char data[48]);  int DES_XOR(char R[48], char L[48],int count);  int DES_Swap(char left[32],char right[32]);  int DES_EncryptBlock(char plainBlock[8], char subKeys[16][48], char cipherBlock[8]);  int DES_DecryptBlock(char cipherBlock[8], char subKeys[16][48], char plainBlock[8]);  int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);  int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile);   int ByteToBit(char ch, char bit[8]){  	int cnt;  	for(cnt = 0;cnt < 8; cnt++){  		*(bit+cnt) = (ch>>cnt)&1;  	}  	return 0;  }   int BitToByte(char bit[8],char *ch){  	int cnt;  	for(cnt = 0;cnt < 8; cnt++){  		*ch |= *(bit + cnt)<<cnt;  	}  	return 0;  }   int Char8ToBit64(char ch[8],char bit[64]){  	int cnt;  	for(cnt = 0; cnt < 8; cnt++){  		ByteToBit(*(ch+cnt),bit+(cnt<<3));  	}  	return 0;  }    int Bit64ToChar8(char bit[64],char ch[8]){  	int cnt;  	memset(ch,0,8);  	for(cnt = 0; cnt < 8; cnt++){  		BitToByte(bit+(cnt<<3),ch+cnt);  	}  	return 0;  }   int DES_MakeSubKeys(char key[64],char subKeys[16][48]){  	char temp[56];  	int cnt;  	DES_PC1_Transform(key,temp); 	for(cnt = 0; cnt < 16; cnt++){ 		DES_ROL(temp,MOVE_TIMES[cnt]); 		DES_PC2_Transform(temp,subKeys[cnt]); 	}  	return 0;  }   int DES_PC1_Transform(char key[64], char tempbts[56]){  	int cnt;  	for(cnt = 0; cnt < 56; cnt++){  		tempbts[cnt] = key[PC_1[cnt]];  	}  	return 0;  }   int DES_PC2_Transform(char key[56], char tempbts[48]){  	int cnt;  	for(cnt = 0; cnt < 48; cnt++){  		tempbts[cnt] = key[PC_2[cnt]];  	}  	return 0;  }   int DES_ROL(char data[56], int time){  	char temp[56];  	memcpy(temp,data,time);  	memcpy(temp+time,data+28,time);  	memcpy(data,data+time,28-time);  	memcpy(data+28-time,temp,time);  	memcpy(data+28,data+28+time,28-time);  	memcpy(data+56-time,temp+time,time);  	return 0;  }   int DES_IP_Transform(char data[64]){  	int cnt;  	char temp[64];  	for(cnt = 0; cnt < 64; cnt++){  		temp[cnt] = data[IP_Table[cnt]];  	}  	memcpy(data,temp,64);  	return 0;  }   int DES_IP_1_Transform(char data[64]){  	int cnt;  	char temp[64];  	for(cnt = 0; cnt < 64; cnt++){  		temp[cnt] = data[IP_1_Table[cnt]];  	}  	memcpy(data,temp,64);  	return 0;  }   int DES_E_Transform(char data[48]){  	int cnt;  	char temp[48];  	for(cnt = 0; cnt < 48; cnt++){  		temp[cnt] = data[E_Table[cnt]];  	}  	memcpy(data,temp,48);  	return 0;  }   int DES_P_Transform(char data[32]){  	int cnt;  	char temp[32];  	for(cnt = 0; cnt < 32; cnt++){  		temp[cnt] = data[P_Table[cnt]];  	}  	memcpy(data,temp,32);  	return 0;  }   int DES_XOR(char R[48], char L[48] ,int count){  	int cnt;  	for(cnt = 0; cnt < count; cnt++){  		R[cnt] ^= L[cnt];  	}  	return 0;  }   int DES_SBOX(char data[48]){  	int cnt;  	int line,row,output;  	int cur1,cur2;  	for(cnt = 0; cnt < 8; cnt++){  		cur1 = cnt*6;  		cur2 = cnt<<2;   		line = (data[cur1]<<1) + data[cur1+5];  		row = (data[cur1+1]<<3) + (data[cur1+2]<<2)  			+ (data[cur1+3]<<1) + data[cur1+4];  		output = S[cnt][line][row];   		data[cur2] = (output&0X08)>>3;  		data[cur2+1] = (output&0X04)>>2;  		data[cur2+2] = (output&0X02)>>1;  		data[cur2+3] = output&0x01;  	}  	return 0;  }   int DES_Swap(char left[32], char right[32]){  	char temp[32];  	memcpy(temp,left,32);  	memcpy(left,right,32);  	memcpy(right,temp,32);  	return 0;  }   int DES_EncryptBlock(char plainBlock[8], char subKeys[16][48], char cipherBlock[8]){  	char plainBits[64];  	char copyRight[48];  	int cnt;  	Char8ToBit64(plainBlock,plainBits);   	DES_IP_Transform(plainBits);  	for(cnt = 0; cnt < 16; cnt++){  		memcpy(copyRight,plainBits+32,32);  		DES_E_Transform(copyRight);  		DES_XOR(copyRight,subKeys[cnt],48);  		DES_SBOX(copyRight);  		DES_P_Transform(copyRight);  		DES_XOR(plainBits,copyRight,32);  		if(cnt != 15){  			DES_Swap(plainBits,plainBits+32);  		}  	}  	DES_IP_1_Transform(plainBits);  	Bit64ToChar8(plainBits,cipherBlock);  	return 0;  }  楼主，你的置换码表是不是不对，网上找了好多，都是和你不一样的一个样子 你的 int IP_Table[64] = { 57,49,41,33,25,17,9,1,      59,51,43,35,27,19,11,3,      61,53,45,37,29,21,13,5,      63,55,47,39,31,23,15,7,      56,48,40,32,24,16,8,0,      58,50,42,34,26,18,10,2,      60,52,44,36,28,20,12,4,      62,54,46,38,30,22,14,6};   人家的 int IP_Table[64] = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17,  9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 };  每位都差1

#include <stdio.h> #include <windows.h> #define bool BOOL #define true TRUE #define false FALSE //#include "bool.h"   // 位处理  //#include "tables.h"             // 执行DES解密 //初始置换表IP char IP_Table[64]={57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,56,48,40,32,24,16,8,0,58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54,46,38,30,22,14,6}; //逆初始置换表IP^-1  char IPR_Table[64]={39,7,47,15,55,23,63,31,38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,34,2,42,10,50,18,58,26,33,1,41,9,49,17,57,25,32,0,40,8,48,16,56,24}; //扩充置换表E  char E_Table[48]={31,0,1,2,3,4,3,4,5,6,7,8,7,8,9,10,11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,21,22,23,24,23,24,25,26,27,28,27,28,29,30,31,0};  //置换函数P??  char P_Table[32]={15,6,19,20,28,11,27,16,0,14,22,25,4,17,30,9,1,7,23,13,31,26,2,8,18,12,29,5,21,10,3,24}; //S盒 char S_Box[8][4][16]= {{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7}, {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},  {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},  {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}}, //S2 {{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10}, {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5}, {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15}, {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}}, //S3 {{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},  {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},  {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},  {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}}, //S4  {{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15}, {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9}, {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},  {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}}, //S5 {{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},  {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},  {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14}, {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}}, //S6 {{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11}, {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8}, {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6}, {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}}, //S7 {{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1}, {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6}, {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2}, {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}}, //S8 {{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7}, {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2}, {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8}, {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}}; //置换选择1 char PC1_Table[56]={56,48,40,32,24,16,8,0,57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,60,52,44,36,28,20,12,4,27,19,11,3}; //置换选择2  char PC2_Table[48]={13,16,10,23,0,4,2,27,14,5,20,9,22,18,11,3,25,7,15,6,26,19,12,1,40,51,30,36,46,54,29,39,50,44,32,46,43,48,38,55,33,52,45,41,49,35,28,31};  //对左移次数的规定??  char Move_Table[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};  int main() { 	int flag=1; 	printf("************Welcome!************\n"); 	while(flag==1) 	{ 		void BitsCopy(bool *DatOut,bool *DatIn,int Len);  // 数组复制          void ByteToBit(bool *DatOut,char *DatIn,int Num); // 字节到位          void BitToByte(char *DatOut,bool *DatIn,int Num); // 位到字节         void BitToHex(char *DatOut,bool *DatIn,int Num);  // 二进制到十六进制 64位 to 4*16字符         void HexToBit(bool *DatOut,char *DatIn,int Num);  // 十六进制到二进制          void LoopMove(bool *DatIn,int Len,int Num);     // 循环左移 Len长度 Num移动位数          void Xor(bool *DatA,bool *DatB,int Num);         // 异或函数          void S_Change(bool DatOut[32],bool DatIn[48]);   // S盒变换          void F_Change(bool DatIn[32],bool DatKi[48]);    // F函数                                           void SetKey(char KeyIn[8]);                         // 设置密钥         void PlayDes(char MesOut[8],char MesIn[64]);       // 执行DES加密         void KickDes(char MesOut[64],char MesIn[8]);  	    int i=0,t=0;  	    char MesHex[64]={0};         // 16个字符数组用于存放 64位16进制的密文  	    char MyKey[8]={0};           // 初始密钥 8字节*8 	    char YourKey[8]={0};         // 输入的解密密钥 8字节*8     	char MyMessage[64]={0};       // 初始明文  	    printf("Please input your Message(64 bit):\n"); 		scanf("%s",MyMessage);           // 明文 	    printf("Please input your Secret Key(Notice:The password must be eight bit):\n"); 		scanf("%s",MyKey);             // 密钥 	    while(MyKey[i]!='\0')        // 计算密钥长度 		{ 			i++; 		}  	    while(i!=8)                  // 不是8 提示错误 		{ 			printf("Please input a correct Secret Key!\n"); 			t=1;break; 		} 		if(t==1) 			scanf("%s",MyKey); 		i=0; 		while(MyKey[i]!='\0')    // 再次检测 		{ 			i++; 		} 	   SetKey(MyKey);               // 设置密钥 得到子密钥Ki 	   PlayDes(MesHex,MyMessage);   // 执行DES加密 	   printf("Your Message is Encrypted!:\n");  // 信息已加密 	   for(i=0;i<16;i++)            	   { 		   printf("%c  ",MesHex[i]); 	   } 	   printf("\n"); 	   printf("\n"); 	   printf("Please input your Secret Key to Deciphering:\n");  // 请输入密钥以解密 	   scanf("%s",YourKey);                                         // 得到密钥 	   SetKey(YourKey);                                       // 设置密钥 	   KickDes(MyMessage,MesHex);                     // 解密输出到MyMessage 	   printf("Deciphering Over !!:\n");// 解密结 	   for(i=0;i<64;i++) 	   { 		   printf("%c ",MyMessage[i]); 	   } 	   printf("\n"); 	   printf("if continue:please press 1\n"); 	   printf("if end     :please press 0\n"); 	   scanf("%d",&flag); 	   system("cls"); 	} 	return 0; } void BitsCopy(bool *DatOut,bool *DatIn,int Len)     // 数组复制 OK  { 	int i=0; 	for(i=0;i<Len;i++) 	{ 		DatOut[i]=DatIn[i]; 	} } void ByteToBit(bool *DatOut,char *DatIn,int Num)       // OK { 	int i=0; 	for(i=0;i<Num;i++) 	{ 		DatOut[i]=(DatIn[i/8]>>(i%8))&0x01;    	}                                        } void BitToByte(char *DatOut,bool *DatIn,int Num)        // OK { 	int i=0; 	for(i=0;i<(Num/8);i++) 	{ 		DatOut[i]=0; 	}  	for(i=0;i<Num;i++) 	{ 		DatOut[i/8]|=DatIn[i]<<(i%8);	 	}		 } void BitToHex(char *DatOut,bool *DatIn,int Num) { 	int i=0; 	for(i=0;i<Num/4;i++) 	{ 		DatOut[i]=0; 	} 	for(i=0;i<Num/4;i++) 	{ 		DatOut[i] = DatIn[i*4]+(DatIn[i*4+1]<<1) 					+(DatIn[i*4+2]<<2)+(DatIn[i*4+3]<<3); 		if((DatOut[i]%16)>9) 		{ 			DatOut[i]=DatOut[i]%16+'7';       //  余数大于9时处理 10-15 to A-F 		}                                     //  输出字符  		else 		{ 			DatOut[i]=DatOut[i]%16+'0';       //  输出字符	    		} 	} } void HexToBit(bool *DatOut,char *DatIn,int Num) { 	int i=0;                        // 字符型输入  	for(i=0;i<Num;i++) 	{ 		if((DatIn[i/4])>'9')         //  大于9  		{ 			DatOut[i]=((DatIn[i/4]-'7')>>(i%4))&0x01;   			 		} 		else 		{ 			DatOut[i]=((DatIn[i/4]-'0')>>(i%4))&0x01; 	 		}  	}	 } // 表置换函数  OK void TablePermute(bool *DatOut,bool *DatIn,const char *Table,int Num)   { 	int i=0; 	static bool Temp[256]={0}; 	for(i=0;i<Num;i++)                // Num为置换的长度  	{ 		Temp[i]=DatIn[Table[i]-1];  // 原来的数据按对应的表上的位置排列  	} 	BitsCopy(DatOut,Temp,Num);       // 把缓存Temp的值输出  }  // 子密钥的移位 void LoopMove(bool *DatIn,int Len,int Num) // 循环左移 Len数据长度 Num移动位数 { 	static bool Temp[256]={0};    // 缓存   OK 	BitsCopy(Temp,DatIn,Num);       // 将数据最左边的Num位(被移出去的)存入Temp  	BitsCopy(DatIn,DatIn+Num,Len-Num); // 将数据左边开始的第Num移入原来的空间 	BitsCopy(DatIn+Len-Num,Temp,Num);  // 将缓存中移出去的数据加到最右边  }  // 按位异或 void Xor(bool *DatA,bool *DatB,int Num)           // 异或函数 { 	int i=0; 	for(i=0;i<Num;i++) 	{ 		DatA[i]=DatA[i]^DatB[i];                  // 异或  	} }  // 输入48位 输出32位 与Ri异或 void S_Change(bool DatOut[32],bool DatIn[48])     // S盒变换 { 	int i,X,Y;                                    // i为8个S盒  	for(i=0,Y=0,X=0;i<8;i++,DatIn+=6,DatOut+=4)   // 每执行一次,输入数据偏移6位  	{    										  // 每执行一次,输出数据偏移4位 		Y=(DatIn[0]<<1)+DatIn[5];                          // af代表第几行 		X=(DatIn[1]<<3)+(DatIn[2]<<2)+(DatIn[3]<<1)+DatIn[4]; // bcde代表第几列 		ByteToBit(DatOut,&S_Box[i][Y][X],4);      // 把找到的点数据换为二进制	 	} } // F函数 void F_Change(bool DatIn[32],bool DatKi[48])       // F函数 { 	static bool MiR[48]={0};             // 输入32位通过E选位变为48位 	TablePermute(MiR,DatIn,E_Table,48);  	Xor(MiR,DatKi,48);                   // 和子密钥异或 	S_Change(DatIn,MiR);                 // S盒变换 	TablePermute(DatIn,DatIn,P_Table,32);   // P置换后输出 } void SetKey(char KeyIn[8])               // 设置密钥 获取子密钥Ki  { 	int i=0; 	static bool SubKey[16]; 	static bool KeyBit[64]={0};                // 密钥二进制存储空间  	static bool *KiL=&KeyBit[0],*KiR=&KeyBit[28];  // 前28,后28共56 	ByteToBit(KeyBit,KeyIn,64);                    // 把密钥转为二进制存入KeyBit  	TablePermute(KeyBit,KeyBit,PC1_Table,56);      // PC1表置换 56次 	for(i=0;i<16;i++) 	{ 		LoopMove(KiL,28,Move_Table[i]);       // 前28位左移  		LoopMove(KiR,28,Move_Table[i]);	      // 后28位左移  	 	TablePermute(SubKey,KeyBit,PC2_Table,48);  	 	// 二维数组 SubKey[i]为每一行起始地址  	 	// 每移一次位进行PC2置换得 Ki 48位  	}		 } void PlayDes(char MesOut[8],char MesIn[64])  // 执行DES加密 {                                           // 字节输入 Bin运算 Hex输出  	int i=0; 	static bool SubKey[16]; 	static bool MesBit[64]={0};        // 明文二进制存储空间 64位 	static bool Temp[32]={0}; 	static bool *MiL=&MesBit[0],*MiR=&MesBit[32]; // 前32位 后32位  	ByteToBit(MesBit,MesIn,64);                 // 把明文换成二进制存入MesBit 	TablePermute(MesBit,MesBit,IP_Table,64);    // IP置换  	for(i=0;i<16;i++)                       // 迭代16次  	{ 		BitsCopy(Temp,MiR,32);            // 临时存储 		F_Change(MiR,SubKey[i]);           // F函数变换 		Xor(MiR,MiL,32);                  // 得到Ri  		BitsCopy(MiL,Temp,32);            // 得到Li  	}					 	TablePermute(MesBit,MesBit,IPR_Table,64); 	BitToHex(MesOut,MesBit,64); } void KickDes(char MesOut[64],char MesIn[8])       // 执行DES解密 {												// Hex输入 Bin运算 字节输出  	int i=0; 	static bool SubKey[16]; 	static bool MesBit[64]={0};        // 密文二进制存储空间 64位 	static bool Temp[32]={0}; 	static bool *MiL=&MesBit[0],*MiR=&MesBit[32]; // 前32位 后32位 	HexToBit(MesBit,MesIn,64);                 // 把密文换成二进制存入MesBit 	TablePermute(MesBit,MesBit,IP_Table,64);    // IP置换  	for(i=15;i>=0;i--) 	{ 		BitsCopy(Temp,MiL,32); 		F_Change(MiL,SubKey[i]); 		Xor(MiL,MiR,32); 		BitsCopy(MiR,Temp,32); 	}	 	TablePermute(MesBit,MesBit,IPR_Table,64); 	BitToByte(MesOut,MesBit,64);		 }  TablePermute(KeyBit,KeyBit,PC1_Table,56);      // PC1表置换 56 显示错误 warning C4047: 'function' : 'int *' differs in levels of indirection from 'int ' 怎么解决

如果结果不一致，代码肯定不对啊

这篇是delphi的，不知道译C++CB能不能用 以下为c,delphi的des加密解密算法，现在除了中文外其余的，都没问题。哪位帮忙看看是何原因，谢谢！ unit DESUnit; interface uses     SysUtils;  function DESEncryptStr(Str, Key: String): String; function DESDecryptStr(Str, Key: String): String; function DESEncryptStrToHex(Str, Key: String): String; function DESDecryptStrFromHex(StrHex, Key: String): String; implementation const     BitIP: array[0..63] of Byte =     (57, 49, 41, 33, 25, 17, 9, 1,       59, 51, 43, 35, 27, 19, 11, 3,       61, 53, 45, 37, 29, 21, 13, 5,       63, 55, 47, 39, 31, 23, 15, 7,       56, 48, 40, 32, 24, 16, 8, 0,       58, 50, 42, 34, 26, 18, 10, 2,       60, 52, 44, 36, 28, 20, 12, 4,       62, 54, 46, 38, 30, 22, 14, 6);    BitCP: array[0..63] of Byte =     (39, 7, 47, 15, 55, 23, 63, 31,       38, 6, 46, 14, 54, 22, 62, 30,       37, 5, 45, 13, 53, 21, 61, 29,       36, 4, 44, 12, 52, 20, 60, 28,       35, 3, 43, 11, 51, 19, 59, 27,       34, 2, 42, 10, 50, 18, 58, 26,       33, 1, 41, 9, 49, 17, 57, 25,       32, 0, 40, 8, 48, 16, 56, 24);    BitExp: array[0..47] of Byte =     (31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10,       11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20,       21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0);    BitPM: array[0..31] of Byte =     (15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9,       1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24);    sBox: array[0..7] of array[0..63] of Byte =     ((14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,       0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,       4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,       15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13),      (15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,       3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,       0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,       13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9),      (10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,       13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,       13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,       1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12),      (7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,       13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,       10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,       3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14),      (2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,       14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,       4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,       11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3),      (12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,       10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,       9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,       4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13),      (4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,       13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,       1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,       6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12),      (13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,       1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,       7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,       2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11));    BitPMC1: array[0..55] of Byte =     (56, 48, 40, 32, 24, 16, 8,       0, 57, 49, 41, 33, 25, 17,       9, 1, 58, 50, 42, 34, 26,       18, 10, 2, 59, 51, 43, 35,       62, 54, 46, 38, 30, 22, 14,       6, 61, 53, 45, 37, 29, 21,       13, 5, 60, 52, 44, 36, 28,       20, 12, 4, 27, 19, 11, 3);    BitPMC2: array[0..47] of Byte =     (13, 16, 10, 23, 0, 4,       2, 27, 14, 5, 20, 9,       22, 18, 11, 3, 25, 7,       15, 6, 26, 19, 12, 1,       40, 51, 30, 36, 46, 54,       29, 39, 50, 44, 32, 47,       43, 48, 38, 55, 33, 52,       45, 41, 49, 35, 28, 31); type     TKeyByte = array[0..5] of Byte;     TDesMode = (dmEncry, dmDecry); var     subKey: array[0..15] of TKeyByte;  procedure InitPermutation(var inData: array of Byte);  var     newData: array[0..7] of Byte;     I: Integer;  begin     FillChar(newData, 8, 0);     for I := 0 to 63 do       if (inData[BitIP[I] shr 3] and (1 shl (7 - (BitIP[I] and $07)))) <> 0 then         newData[I shr 3] := newData[I shr 3] or (1 shl (7 - (I and $07)));     for I := 0 to 7 do inData[I] := newData[I];  end; procedure ConversePermutation(var inData: array of Byte);  var     newData: array[0..7] of Byte;     I: Integer;  begin     FillChar(newData, 8, 0);     for I := 0 to 63 do       if (inData[BitCP[I] shr 3] and (1 shl (7 - (BitCP[I] and $07)))) <> 0 then         newData[I shr 3] := newData[I shr 3] or (1 shl (7 - (I and $07)));     for I := 0 to 7 do inData[I] := newData[I];  end; procedure Expand(inData: array of Byte; var outData: array of Byte);  var     I: Integer;  begin     FillChar(outData, 6, 0);     for I := 0 to 47 do       if (inData[BitExp[I] shr 3] and (1 shl (7 - (BitExp[I] and $07)))) <> 0 then         outData[I shr 3] := outData[I shr 3] or (1 shl (7 - (I and $07)));  end; procedure Permutation(var inData: array of Byte);  var     newData: array[0..3] of Byte;     I: Integer;  begin     FillChar(newData, 4, 0);     for I := 0 to 31 do       if (inData[BitPM[I] shr 3] and (1 shl (7 - (BitPM[I] and $07)))) <> 0 then         newData[I shr 3] := newData[I shr 3] or (1 shl (7 - (I and $07)));     for I := 0 to 3 do inData[I] := newData[I];  end; function Si(s, inByte: Byte): Byte;  var     c: Byte;  begin     c := (inByte and $20) or ((inByte and $1E) shr 1) or       ((inByte and $01) shl 4);     Result := (sBox[s][c] and $0F);  end; procedure PermutationChoose1(inData: array of Byte; var outData: array of Byte);  var     I: Integer;  begin     FillChar(outData, 7, 0);     for I := 0 to 55 do       if (inData[BitPMC1[I] shr 3] and (1 shl (7 - (BitPMC1[I] and $07)))) <> 0 then         outData[I shr 3] := outData[I shr 3] or (1 shl (7 - (I and $07)));  end;

procedure PermutationChoose2(inData: array of Byte; var outData: array of Byte);    var       I: Integer;    begin       FillChar(outData, 6, 0);       for I := 0 to 47 do         if (inData[BitPMC2[I] shr 3] and (1 shl (7 - (BitPMC2[I] and $07)))) <> 0 then           outData[I shr 3] := outData[I shr 3] or (1 shl (7 - (I and $07)));    end;   procedure cycleMove(var inData: array of Byte; bitMove: Byte);    var       I: Integer;    begin       for I := 0 to bitMove - 1 do       begin         inData[0] := (inData[0] shl 1) or (inData[1] shr 7);         inData[1] := (inData[1] shl 1) or (inData[2] shr 7);         inData[2] := (inData[2] shl 1) or (inData[3] shr 7);         inData[3] := (inData[3] shl 1) or ((inData[0] and $10) shr 4);         inData[0] := (inData[0] and $0F);       end;    end;   procedure MakeKey(inKey: array of Byte; var outKey: array of TKeyByte);    const       bitDisplace: array[0..15] of Byte =       (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1);    var       outData56: array[0..6] of Byte;       key28l: array[0..3] of Byte;       key28r: array[0..3] of Byte;       key56o: array[0..6] of Byte;       I: Integer;    begin       permutationChoose1(inKey, outData56);       key28l[0] := outData56[0] shr 4;       key28l[1] := (outData56[0] shl 4) or (outData56[1] shr 4);       key28l[2] := (outData56[1] shl 4) or (outData56[2] shr 4);       key28l[3] := (outData56[2] shl 4) or (outData56[3] shr 4);       key28r[0] := outData56[3] and $0F;       key28r[1] := outData56[4];       key28r[2] := outData56[5];       key28r[3] := outData56[6];       for I := 0 to 15 do       begin         cycleMove(key28l, bitDisplace[I]);         cycleMove(key28r, bitDisplace[I]);         key56o[0] := (key28l[0] shl 4) or (key28l[1] shr 4);         key56o[1] := (key28l[1] shl 4) or (key28l[2] shr 4);         key56o[2] := (key28l[2] shl 4) or (key28l[3] shr 4);         key56o[3] := (key28l[3] shl 4) or (key28r[0]);         key56o[4] := key28r[1];         key56o[5] := key28r[2];         key56o[6] := key28r[3];         permutationChoose2(key56o, outKey[I]);       end;    end;   procedure Encry(inData, subKey: array of Byte; var outData: array of Byte);    var       outBuf: array[0..5] of Byte;       buf: array[0..7] of Byte;       I: Integer;    begin       expand(inData, outBuf);       for I := 0 to 5 do outBuf[I] := outBuf[I] xor subKey[I];       buf[0] := outBuf[0] shr 2;       buf[1] := ((outBuf[0] and $03) shl 4) or (outBuf[1] shr 4);       buf[2] := ((outBuf[1] and $0F) shl 2) or (outBuf[2] shr 6);       buf[3] := outBuf[2] and $3F;       buf[4] := outBuf[3] shr 2;       buf[5] := ((outBuf[3] and $03) shl 4) or (outBuf[4] shr 4);       buf[6] := ((outBuf[4] and $0F) shl 2) or (outBuf[5] shr 6);       buf[7] := outBuf[5] and $3F;       for I := 0 to 7 do buf[I] := si(I, buf[I]);       for I := 0 to 3 do outBuf[I] := (buf[I * 2] shl 4) or buf[I * 2 + 1];       permutation(outBuf);       for I := 0 to 3 do outData[I] := outBuf[I];    end;   procedure DesData(desMode: TDesMode; inData: array of Byte; var outData: array         of Byte);    var       I, j: Integer;       temp, buf: array[0..3] of Byte;    begin       for I := 0 to 7 do outData[I] := inData[I];       initPermutation(outData);       if desMode = dmEncry then       begin         for I := 0 to 15 do         begin           for j := 0 to 3 do temp[j] := outData[j];           for j := 0 to 3 do outData[j] := outData[j + 4];           encry(outData, subKey[I], buf);           for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j];         end;         for j := 0 to 3 do temp[j] := outData[j + 4];         for j := 0 to 3 do outData[j + 4] := outData[j];         for j := 0 to 3 do outData[j] := temp[j];       end       else if desMode = dmDecry then       begin         for I := 15 downto 0 do         begin           for j := 0 to 3 do temp[j] := outData[j];           for j := 0 to 3 do outData[j] := outData[j + 4];           encry(outData, subKey[I], buf);           for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j];         end;         for j := 0 to 3 do temp[j] := outData[j + 4];         for j := 0 to 3 do outData[j + 4] := outData[j];         for j := 0 to 3 do outData[j] := temp[j];       end;       conversePermutation(outData);    end;

贴的代码不全啊，我也看过这段代码

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }

C语言区怎么回事啊，100分的题，居然没有想要的答案

引用 6 楼 hemowolf 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 那就用hemowolf的代码。  前三楼都是楼主，大侠 因为一个帖子不能超过10000个字，所以分三帖了[/quote] 哦？！看走眼了。  参考：openssl\crypto\des\des*.*

引用 8 楼 hemowolf 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] [quote=引用 6 楼 hemowolf 的回复:] [quote=引用 5 楼 zhao4zhong1 的回复:] 那就用hemowolf的代码。  前三楼都是楼主，大侠 因为一个帖子不能超过10000个字，所以分三帖了[/quote] 哦？！看走眼了。  参考：openssl\crypto\des\des*.*[/quote]  这是什么东东？ URL吗？[/quote] 下载openssl源代码。

引用 7 楼 zhao4zhong1 的回复:[quote=引用 6 楼 hemowolf 的回复:] [quote=引用 5 楼 zhao4zhong1 的回复:] 那就用hemowolf的代码。  前三楼都是楼主，大侠 因为一个帖子不能超过10000个字，所以分三帖了[/quote] 哦？！看走眼了。  参考：openssl\crypto\des\des*.*[/quote]  这是什么东东？ URL吗？

仅供参考：#pragma comment(lib, "crypt32.lib") #pragma comment(lib, "advapi32.lib") #define _WIN32_WINNT 0x0400 #include <stdio.h> #include <windows.h> #include <wincrypt.h> #define KEYLENGTH  0x00800000 void HandleError(char *s); //-------------------------------------------------------------------- //  These additional #define statements are required. #define ENCRYPT_ALGORITHM CALG_RC4 #define ENCRYPT_BLOCK_SIZE 8 //   Declare the function EncryptFile. The function definition //   follows main. BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword); //-------------------------------------------------------------------- //   Begin main. void main(void) {     CHAR szSource[100];     CHAR szDestination[100];     CHAR szPassword[100];     printf("Encrypt a file. \n\n");     printf("Enter the name of the file to be encrypted: ");     scanf("%s",szSource);     printf("Enter the name of the output file: ");     scanf("%s",szDestination);     printf("Enter the password:");     scanf("%s",szPassword);     //--------------------------------------------------------------------     // Call EncryptFile to do the actual encryption.     if(EncryptFile(szSource, szDestination, szPassword)) {         printf("Encryption of the file %s was a success. \n", szSource);         printf("The encrypted data is in file %s.\n",szDestination);     } else {         HandleError("Error encrypting file!");     } } // End of main //-------------------------------------------------------------------- //   Code for the function EncryptFile called by main. static BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword) //-------------------------------------------------------------------- //   Parameters passed are: //     szSource, the name of the input, a plaintext file. //     szDestination, the name of the output, an encrypted file to be //         created. //     szPassword, the password. {     //--------------------------------------------------------------------     //   Declare and initialize local variables.     FILE *hSource;     FILE *hDestination;     HCRYPTPROV hCryptProv;     HCRYPTKEY hKey;     HCRYPTHASH hHash;     PBYTE pbBuffer;     DWORD dwBlockLen;     DWORD dwBufferLen;     DWORD dwCount;     //--------------------------------------------------------------------     // Open source file.     if(hSource = fopen(szSource,"rb")) {         printf("The source plaintext file, %s, is open. \n", szSource);     } else {         HandleError("Error opening source plaintext file!");     }     //--------------------------------------------------------------------     // Open destination file.     if(hDestination = fopen(szDestination,"wb")) {         printf("Destination file %s is open. \n", szDestination);     } else {         HandleError("Error opening destination ciphertext file!");     }     //以下获得一个CSP句柄     if(CryptAcquireContext(                 &hCryptProv,                 NULL,               //NULL表示使用默认密钥容器，默认密钥容器名                 //为用户登陆名                 NULL,                 PROV_RSA_FULL,                 0)) {         printf("A cryptographic provider has been acquired. \n");     } else {         if(CryptAcquireContext(                     &hCryptProv,                     NULL,                     NULL,                     PROV_RSA_FULL,                     CRYPT_NEWKEYSET))//创建密钥容器         {             //创建密钥容器成功，并得到CSP句柄             printf("A new key container has been created.\n");         } else {             HandleError("Could not create a new key container.\n");         }     }     //--------------------------------------------------------------------     // 创建一个会话密钥（session key）     // 会话密钥也叫对称密钥，用于对称加密算法。     // （注: 一个Session是指从调用函数CryptAcquireContext到调用函数     //   CryptReleaseContext 期间的阶段。会话密钥只能存在于一个会话过程）     //--------------------------------------------------------------------     // Create a hash object.     if(CryptCreateHash(                 hCryptProv,                 CALG_MD5,                 0,                 0,                 &hHash)) {         printf("A hash object has been created. \n");     } else {         HandleError("Error during CryptCreateHash!\n");     }     //--------------------------------------------------------------------     // 用输入的密码产生一个散列     if(CryptHashData(                 hHash,                 (BYTE *)szPassword,                 strlen(szPassword),                 0)) {         printf("The password has been added to the hash. \n");     } else {         HandleError("Error during CryptHashData. \n");     }     //--------------------------------------------------------------------     // 通过散列生成会话密钥     if(CryptDeriveKey(                 hCryptProv,                 ENCRYPT_ALGORITHM,                 hHash,                 KEYLENGTH,                 &hKey)) {         printf("An encryption key is derived from the password hash. \n");     } else {         HandleError("Error during CryptDeriveKey!\n");     }     //--------------------------------------------------------------------     // Destroy the hash object.     CryptDestroyHash(hHash);     hHash = NULL;     //--------------------------------------------------------------------     //  The session key is now ready.     //--------------------------------------------------------------------     // 因为加密算法是按ENCRYPT_BLOCK_SIZE 大小的块加密的，所以被加密的     // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的     // 数据长度。     dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;     //--------------------------------------------------------------------     // Determine the block size. If a block cipher is used,     // it must have room for an extra block.     if(ENCRYPT_BLOCK_SIZE > 1)         dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;     else         dwBufferLen = dwBlockLen;     //--------------------------------------------------------------------     // Allocate memory.     if(pbBuffer = (BYTE *)malloc(dwBufferLen)) {         printf("Memory has been allocated for the buffer. \n");     } else {         HandleError("Out of memory. \n");     }     //--------------------------------------------------------------------     // In a do loop, encrypt the source file and write to the destination file.     do {         //--------------------------------------------------------------------         // Read up to dwBlockLen bytes from the source file.         dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);         if(ferror(hSource)) {             HandleError("Error reading plaintext!\n");         }         //--------------------------------------------------------------------         // 加密数据         if(!CryptEncrypt(                     hKey,           //密钥                     0,              //如果数据同时进行散列和加密，这里传入一个                     //散列对象                     feof(hSource),  //如果是最后一个被加密的块，输入TRUE.如果不是输.                     //入FALSE这里通过判断是否到文件尾来决定是否为                     //最后一块。                     0,              //保留                     pbBuffer,       //输入被加密数据，输出加密后的数据                     &dwCount,       //输入被加密数据实际长度，输出加密后数据长度                     dwBufferLen))   //pbBuffer的大小。         {             HandleError("Error during CryptEncrypt. \n");         }         //--------------------------------------------------------------------         // Write data to the destination file.         fwrite(pbBuffer, 1, dwCount, hDestination);         if(ferror(hDestination)) {             HandleError("Error writing ciphertext.");         }     } while(!feof(hSource));     //--------------------------------------------------------------------     //  End the do loop when the last block of the source file has been     //  read, encrypted, and written to the destination file.     //--------------------------------------------------------------------     // Close files.     if(hSource)         fclose(hSource);     if(hDestination)         fclose(hDestination);     //--------------------------------------------------------------------     // Free memory.     if(pbBuffer)         free(pbBuffer);     //--------------------------------------------------------------------     // Destroy session key.     if(hKey)         CryptDestroyKey(hKey);     //--------------------------------------------------------------------     // Destroy hash object.     if(hHash)         CryptDestroyHash(hHash);     //--------------------------------------------------------------------     // Release provider handle.     if(hCryptProv)         CryptReleaseContext(hCryptProv, 0);     return(TRUE); } // End of Encryptfile //-------------------------------------------------------------------- //  This example uses the function HandleError, a simple error //  handling function, to print an error message to the standard error //  (stderr) file and exit the program. //  For most applications, replace this function with one //  that does more extensive error reporting. void HandleError(char *s) {     fprintf(stderr,"An error occurred in running the program. \n");     fprintf(stderr,"%s\n",s);     fprintf(stderr, "Error number %x.\n", GetLastError());     fprintf(stderr, "Program terminating. \n");     exit(1); } // End of HandleError

int DES_DecryptBlock(char cipherBlock[8], char subKeys[16][48],char plainBlock[8]){  	char cipherBits[64];  	char copyRight[48];  	int cnt;  	Char8ToBit64(cipherBlock,cipherBits);  	DES_IP_Transform(cipherBits);  	for(cnt = 15; cnt >= 0; cnt--){  		memcpy(copyRight,cipherBits+32,32);  		DES_E_Transform(copyRight);  		DES_XOR(copyRight,subKeys[cnt],48);  		DES_SBOX(copyRight);  		DES_P_Transform(copyRight);  		DES_XOR(cipherBits,copyRight,32);  		if(cnt != 0){  			DES_Swap(cipherBits,cipherBits+32);  		}  	}   	DES_IP_1_Transform(cipherBits);  	Bit64ToChar8(cipherBits,plainBlock);  	return 0;   }  /* 加密 */  char* DES_Encrypt(char *sourceData, int sourceSize, char *keyStr, int *resultSize){ 	 	char *destData = 0; 	int destSize = sourceSize; 	if(destSize % 8 != 0) 		destSize += (8 - (destSize % 8)); 	destData = (char*)malloc(destSize); 	*resultSize = destSize; 	 	int count;  	char sourceBlock[8], destBlock[8], keyBlock[8];  	char bKey[64];  	char subKeys[16][48]; 	 	memcpy(keyBlock, keyStr, 8); 	Char8ToBit64(keyBlock,bKey);  	DES_MakeSubKeys(bKey,subKeys); 	int p = 0; 	while(p + 8 <= sourceSize){ 		memcpy(sourceBlock, sourceData + p, sizeof(sourceBlock)); 		DES_EncryptBlock(sourceBlock, subKeys, destBlock); 		memcpy(destData + p, destBlock, sizeof(destBlock)); 		p += 8; 	} 	 	if(p + 8 > sourceSize){ 		memset(sourceBlock, '\0', 8); 		// sourceBlock[7] = 8 - (sourceSize % 8); 		memcpy(sourceBlock, sourceData + p, sourceSize % 8); 		DES_EncryptBlock(sourceBlock, subKeys, destBlock); 		memcpy(destData + p, destBlock, sizeof(destBlock)); 	} 	 	return destData; }   char* DES_Decrypt(char *sourceData, int sourceSize, char *keyStr, int* resultSize){ 	 	int count,times = 0;  	long fileLen;  	char sourceBlock[8], destBlock[8], keyBlock[8]; 	char bKey[64];  	char subKeys[16][48]; 	char *destData = (char*)malloc(sourceSize); 	*resultSize = sourceSize; 	 	memcpy(keyBlock,keyStr,8);  	Char8ToBit64(keyBlock,bKey);  	DES_MakeSubKeys(bKey,subKeys);  	 	int p = 0; 	while(p < sourceSize){ 		memcpy(sourceBlock, sourceData + p, 8); 		DES_DecryptBlock(sourceBlock, subKeys, destBlock); 		memcpy(destData + p, destBlock, 8); 		p+= 8; 	} 	 	for(int i=0; i<sourceSize; i++){ 		printf("%d ", 0xFF & destData[i]); 	} 	printf("\r\n"); 	int nullCnt = destData[*resultSize - 1]; 	int realNullCnt = 1; 	int pt = *resultSize - 2; 	int pi = 6; 	while(destData[pt] == '\0' && pi > 0){ 		pt--; 		pi--; 		realNullCnt++; 	} 	printf("nullCnt = %d, realNullCnt = %d\r\n", nullCnt, realNullCnt); 	if(nullCnt != realNullCnt){ 		printf("aaa null byte count = %d\r\n", realNullCnt); 	}else{ 		printf("bbb null byte count = %d\r\n", realNullCnt); 		*resultSize -= realNullCnt; 		char *resultData = (char*)malloc(*resultSize); 		memcpy(resultData, destData, *resultSize); 		free(destData); 		destData = resultData; 	} 	 	return destData; }   int _tmain(int argc, _TCHAR* argv[])  {  	char* pSource = "12345678XYZ"; 	char *pKey = "abcdefgh"; 	int sourceLength = strlen(pSource); 	 	char* source = (char*)malloc(sourceLength); 	char key[8]; 	memcpy(source, pSource, sourceLength); 	memcpy(key, pKey, 8); 	char *dest; 	int destSize; 	 	printf("Source:\r\n"); 	for(int i=0; i<sourceLength; i++){ 		printf("%d ", 0xFF & source[i]); 	} 	printf("\r\n"); 	dest = DES_Encrypt(source, sourceLength, key, &destSize); 	printf("Encrypt complete:\r\n"); 	for(int i=0; i<destSize; i++){ 		printf("%d ", (0xFF & dest[i])); 	} 	printf("\r\ndestSize = %d\r\n", destSize); 	 	char* dest1 = DES_Decrypt(dest, destSize, key, &destSize); 	printf("destSize = %d\r\n", destSize); 	for(int i=0; i<destSize; i++){ 		printf("%c", dest1[i]); 	} 	printf("\r\n"); 	 	return 0;  }

引用 5 楼 zhao4zhong1 的回复:那就用hemowolf的代码。  前三楼都是楼主，大侠 因为一个帖子不能超过10000个字，所以分三帖了

那就用hemowolf的代码。

楼上的大侠，你的代码是要调用WINDOWS的函数吧  我的终端运行的不是Windows啊


Question: C 如何释放申请的二位动态地址空间

楼主还没发现吗？内循环动态分配空间时是以储存一级指针地址的大小来分配的，你这里空间不足，估计是越界了啊。

仅供参考：#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //

引用 3 楼 yizhizhuen 的回复:说实话，楼主也是6的飞起，我这多年也是头一次看到有人给一个指针类型地址块的！ mazeword = (char **)malloc(m*sizeof(char *)); 去掉上面这个！ 然后去掉 free(mazeword);  就好了！ 并且这一步也是必须的~不然mazeword就是野指针呢

引用 3 楼 yizhizhuen 的回复:说实话，楼主也是6的飞起，我这多年也是头一次看到有人给一个指针类型地址块的！ mazeword = (char **)malloc(m*sizeof(char *)); 去掉上面这个！ 然后去掉 free(mazeword);  就好了！ 应该不是这儿的问题，这儿是为指针申请空间，即先确定了行数，即m个指针变量嘛。 循环退步出来不见得是释放空间的时候退不出来，代码部分没做容错处理，没有考虑空间申请没成功的情况；其他部分，没看出有多少问题，所以还要看你输入的时候是不是有问题。

我修改代码第七行

int main() { 	int m,n; 	//char w[100]; 	char **mazeword;  	scanf("%d,%d",&m,&n); 	//scanf("%s",w);  	mazeword = (char **)malloc(m*sizeof(char *)); 	for (int i=0;i<m;i++) 	{ 		mazeword[i] = (char *)malloc(n*sizeof(char)); 	}  	for (int i=0;i<m;i++) 	{ 		scanf("%s",mazeword[i]); 	}  	for (int j=0;j<m;j++) 	{ 		printf("%c\t",mazeword[j][2]); 	}  	for(int k=0;k<m;k++) 		free(mazeword[k]); 	free(mazeword);  	return 0; }     m,n值输入错误

你百度二维数组如何动态申请地址空间，难道他们的方法有问题？

代码看不出有什么问题。是不是输入的字符串太长了，超过了n

代码看不出有什么问题。是不是输入的字符串太长了，超过了n


Question: 读取csv文件到二维数组

无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

看看是什么数据, 全是整型的话, 用32位也就20KB内存,  如果是字符串的话, 可以考虑用索引, 用32位,  这样索引信息也20KB内存, 如果闲占用多的话,  可以考虑只用行号索引也就300*4,1kb多点.  文件读取很浪费时间的,假如经常读取又比较小, 没准系统直接把它 全部载入缓存, 还不如自己全部加载

读取、忽略。


Question: 编写mystrcmp(), 实现strcmp()功能

引用 9 楼 king191923157 的回复:[quote=引用 8 楼 qq_28839381 的回复:] [quote=引用 6 楼 a1009563517 的回复:] 第10行scanf段错误 引用 6 楼 a1009563517 的回复:第10行scanf段错误原因是什么，为什么改成数组就不会出错？[/quote]  给参数赋值要有存储空间 char *  只是一个指针 ，没有指向地址 用数组是申请了  一个数组长度大小的空间，输入时数据是存在自己申请的内存  要用char * 可以   char *p= new char[XXXX];  不用的时候再delete [/quote]谢谢，明白了

引用 8 楼 qq_28839381 的回复:[quote=引用 6 楼 a1009563517 的回复:] 第10行scanf段错误 引用 6 楼 a1009563517 的回复:第10行scanf段错误原因是什么，为什么改成数组就不会出错？[/quote]  给参数赋值要有存储空间 char *  只是一个指针 ，没有指向地址 用数组是申请了  一个数组长度大小的空间，输入时数据是存在自己申请的内存  要用char * 可以   char *p= new char[XXXX];  不用的时候再delete

引用 6 楼 a1009563517 的回复:第10行scanf段错误 引用 6 楼 a1009563517 的回复:第10行scanf段错误原因是什么，为什么改成数组就不会出错？

引用 4 楼 qq_28839381 的回复:[quote=引用 1 楼 brookmill 的回复:] char *a, *b; 改成 char a[128], b[128];那我的代码为什么会报错？原因是什么？[/quote] 搜一下”野指针“

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

引用 1 楼 brookmill 的回复:char *a, *b; 改成 char a[128], b[128];那我的代码为什么会报错？原因是什么？

引用 楼主 qq_28839381 的回复:#include "stdio.h" #include "string.h" int mystrcmp(char *, char *);  int main(int argc, char const *argv[]) { 	char *a, *b; 	int i;  	scanf("%s%s", a, b); 	i = mystrcmp(a, b); 	printf("%d\n", i);  	return 0; }  int mystrcmp(char *a, char *b) { 	return strlen(a) > strlen(b) ? 1 : 0; }  运行结果： Segmentation fault (core dumped) 请问哪里错了？那我的代码报错的原因在哪里？能说明一下吗？

strcmp不是比较长度的。具体的用法、功能、源代码都很容易找到 http://blog.csdn.net/yushuai007008/article/details/7626446 http://blog.csdn.net/zhao_fu_lu/article/details/20392239

char *a, *b; 改成 char a[128], b[128];


Question: linux父子进程生死

引用 22 楼 jack960330 的回复:[quote=引用 21 楼 adlay 的回复:] [quote=引用 20 楼 jack960330 的回复:] [quote=引用 6 楼 adlay 的回复:] 你起的进程不是因为父进程死了而死的，而是因为它所依赖的会话终端没有了而死的。所以 UNIX 下的 Daemon 进程都有一个脱离终端的步骤才能让一直存在。  你说的也不对，是因为父进程结束，操作系统会发送一个事件给所有的子进程，而这个事件的默认处理是：进程终止[/quote] [/quote] 当子进程停止，同时父进程挂断，内核就会发送SIGHUP信号给子进程[/quote]  引用 23 楼 jack960330 的回复:父进程退出时，进程组成为了孤儿进程组，这时内核就会发出SIGHUP信号  这个对被停止的进程, 是针对那些被按了 Ctrl+Z 的, 或者被 gdb 之类的调试器调试着的进程吧,  现在这个 wireshark 并不处于这个停止的状态, 所以并不是  "因为父进程结束，操作系统会发送一个事件给所有的子进程，而这个事件的默认处理是：进程终止"  吧

引用 20 楼 jack960330 的回复:[quote=引用 6 楼 adlay 的回复:] 你起的进程不是因为父进程死了而死的，而是因为它所依赖的会话终端没有了而死的。所以 UNIX 下的 Daemon 进程都有一个脱离终端的步骤才能让一直存在。  你说的也不对，是因为父进程结束，操作系统会发送一个事件给所有的子进程，而这个事件的默认处理是：进程终止[/quote] 请问发送的是什么信号？操作系统描述这一机制的文档在哪里？别凭自己的想象来判断。  UNIX 只有子进程结束了向父进程发送 SIGCHLD 信号; 终端结束了向属于这个 Session 的进程发送 SIGHUP， SIGHUP 默认行为是终止进程; 没听说过有父进程结束向子进程发信号的， 如果你看到了，请指明发送的是什么信号!

引用 6 楼 adlay 的回复:你起的进程不是因为父进程死了而死的，而是因为它所依赖的会话终端没有了而死的。所以 UNIX 下的 Daemon 进程都有一个脱离终端的步骤才能让一直存在。  你说的也不对，是因为父进程结束，操作系统会发送一个事件给所有的子进程，而这个事件的默认处理是：进程终止

引用 21 楼 adlay 的回复:[quote=引用 20 楼 jack960330 的回复:] [quote=引用 6 楼 adlay 的回复:] 你起的进程不是因为父进程死了而死的，而是因为它所依赖的会话终端没有了而死的。所以 UNIX 下的 Daemon 进程都有一个脱离终端的步骤才能让一直存在。  你说的也不对，是因为父进程结束，操作系统会发送一个事件给所有的子进程，而这个事件的默认处理是：进程终止[/quote] 请问发送的是什么信号？操作系统描述这一机制的文档在哪里？别凭自己的想象来判断。  UNIX 只有子进程结束了向父进程发送 SIGCHLD 信号; 终端结束了向属于这个 Session 的进程发送 SIGHUP， SIGHUP 默认行为是终止进程; 没听说过有父进程结束向子进程发信号的， 如果你看到了，请指明发送的是什么信号! [/quote] 父进程退出时，进程组成为了孤儿进程组，这时内核就会发出SIGHUP信号

引用 21 楼 adlay 的回复:[quote=引用 20 楼 jack960330 的回复:] [quote=引用 6 楼 adlay 的回复:] 你起的进程不是因为父进程死了而死的，而是因为它所依赖的会话终端没有了而死的。所以 UNIX 下的 Daemon 进程都有一个脱离终端的步骤才能让一直存在。  你说的也不对，是因为父进程结束，操作系统会发送一个事件给所有的子进程，而这个事件的默认处理是：进程终止[/quote] 请问发送的是什么信号？操作系统描述这一机制的文档在哪里？别凭自己的想象来判断。  UNIX 只有子进程结束了向父进程发送 SIGCHLD 信号; 终端结束了向属于这个 Session 的进程发送 SIGHUP， SIGHUP 默认行为是终止进程; 没听说过有父进程结束向子进程发信号的， 如果你看到了，请指明发送的是什么信号! [/quote] 当子进程停止，同时父进程挂断，内核就会发送SIGHUP信号给子进程

顶bsnry，所以说LZ不要用自己头脑中的经验去假想别人会怎么做。

引用 17 楼 bsnry 的回复:[quote=引用 7 楼 ForestDB 的回复:] 第三个问题看mib2c的帮助文档。  void netsnmp_init_mib(void) {     const char     *prefix;     char           *env_var, *entry;     PrefixListPtr   pp = &mib_prefixes[0];     char           *st = NULL;      if (Mib)         return;     netsnmp_init_mib_internals();      /*      * Initialise the MIB directory/ies       */     netsnmp_fixup_mib_directory();     env_var = strdup(netsnmp_get_mib_directory());     netsnmp_mibindex_load();      DEBUGMSGTL(("init_mib",                 "Seen MIBDIRS: Looking in '%s' for mib dirs ...\n",                 env_var));      entry = strtok_r(env_var, ENV_SEPARATOR, &st);     while (entry) {         add_mibdir(entry);         entry = strtok_r(NULL, ENV_SEPARATOR, &st);     }     SNMP_FREE(env_var);      env_var = netsnmp_getenv("MIBFILES");     if (env_var != NULL) {         if (*env_var == '+')             entry = strtok_r(env_var+1, ENV_SEPARATOR, &st);         else             entry = strtok_r(env_var, ENV_SEPARATOR, &st);         while (entry) {             add_mibfile(entry, NULL, NULL);             entry = strtok_r(NULL, ENV_SEPARATOR, &st);         }     }      netsnmp_init_mib_internals();      /*      * Read in any modules or mibs requested       */      env_var = netsnmp_getenv("MIBS");     if (env_var == NULL) {         if (confmibs != NULL)             env_var = strdup(confmibs);         else             env_var = strdup(NETSNMP_DEFAULT_MIBS);     } else {         env_var = strdup(env_var);     }     if (env_var && ((*env_var == '+') || (*env_var == '-'))) {         entry =             (char *) malloc(strlen(NETSNMP_DEFAULT_MIBS) + strlen(env_var) + 2);         if (!entry) {             DEBUGMSGTL(("init_mib", "env mibs malloc failed"));             SNMP_FREE(env_var);             return;         } else {             if (*env_var == '+')                 sprintf(entry, "%s%c%s", NETSNMP_DEFAULT_MIBS, ENV_SEPARATOR_CHAR,                         env_var+1);             else                 sprintf(entry, "%s%c%s", env_var+1, ENV_SEPARATOR_CHAR,                         NETSNMP_DEFAULT_MIBS );         }         SNMP_FREE(env_var);         env_var = entry;     }  env_var = netsnmp_getenv("MIBS");     if (env_var && ((*env_var == '+') || (*env_var == '-'))) {  看+号，  这说明+号是代码自身处理。与linux无关。   猜测windows也是如此。这个程序是跨平台的，没有在网上看到windos的使用例子。  但代码是这样处理的。 [/quote]   代码看了一下， windows应该差不多。  只不过env mibs='+'  mib2c  windows肯定是不能这么用的。

引用 7 楼 ForestDB 的回复:第三个问题看mib2c的帮助文档。  void netsnmp_init_mib(void) {     const char     *prefix;     char           *env_var, *entry;     PrefixListPtr   pp = &mib_prefixes[0];     char           *st = NULL;      if (Mib)         return;     netsnmp_init_mib_internals();      /*      * Initialise the MIB directory/ies       */     netsnmp_fixup_mib_directory();     env_var = strdup(netsnmp_get_mib_directory());     netsnmp_mibindex_load();      DEBUGMSGTL(("init_mib",                 "Seen MIBDIRS: Looking in '%s' for mib dirs ...\n",                 env_var));      entry = strtok_r(env_var, ENV_SEPARATOR, &st);     while (entry) {         add_mibdir(entry);         entry = strtok_r(NULL, ENV_SEPARATOR, &st);     }     SNMP_FREE(env_var);      env_var = netsnmp_getenv("MIBFILES");     if (env_var != NULL) {         if (*env_var == '+')             entry = strtok_r(env_var+1, ENV_SEPARATOR, &st);         else             entry = strtok_r(env_var, ENV_SEPARATOR, &st);         while (entry) {             add_mibfile(entry, NULL, NULL);             entry = strtok_r(NULL, ENV_SEPARATOR, &st);         }     }      netsnmp_init_mib_internals();      /*      * Read in any modules or mibs requested       */      env_var = netsnmp_getenv("MIBS");     if (env_var == NULL) {         if (confmibs != NULL)             env_var = strdup(confmibs);         else             env_var = strdup(NETSNMP_DEFAULT_MIBS);     } else {         env_var = strdup(env_var);     }     if (env_var && ((*env_var == '+') || (*env_var == '-'))) {         entry =             (char *) malloc(strlen(NETSNMP_DEFAULT_MIBS) + strlen(env_var) + 2);         if (!entry) {             DEBUGMSGTL(("init_mib", "env mibs malloc failed"));             SNMP_FREE(env_var);             return;         } else {             if (*env_var == '+')                 sprintf(entry, "%s%c%s", NETSNMP_DEFAULT_MIBS, ENV_SEPARATOR_CHAR,                         env_var+1);             else                 sprintf(entry, "%s%c%s", env_var+1, ENV_SEPARATOR_CHAR,                         NETSNMP_DEFAULT_MIBS );         }         SNMP_FREE(env_var);         env_var = entry;     }  env_var = netsnmp_getenv("MIBS");     if (env_var && ((*env_var == '+') || (*env_var == '-'))) {  看+号，  这说明+号是代码自身处理。与linux无关。   猜测windows也是如此。这个程序是跨平台的，没有在网上看到windos的使用例子。  但代码是这样处理的。

引用 6 楼 adlay 的回复:你起的进程不是因为父进程死了而死的，而是因为它所依赖的会话终端没有了而死的。所以 UNIX 下的 Daemon 进程都有一个脱离终端的步骤才能让一直存在。  在桌面双击一个程序呢？  这有会话？  桌面里可以不需要运行终端啊

mib2c是一个perl脚本，估计要看源码，才能搞清楚， +号的意思，  个人觉得与 env无关。

引用 7 楼 ForestDB 的回复:第三个问题看mib2c的帮助文档。    The mib2c tool accepts both SMIv1 and SMIv2 MIBs.         mib2c needs to be able to find and load a MIB file in order to generate C code for the MIB. To enable mib2c to find the MIB        file,  set  the  MIBS  environment  variable to include the MIB file you are using.  An example of setting this environment        variable is:            MIBS=+NET-SNMP-TUTORIAL-MIB            or            MIBS=ALL

引用 13 楼 jack960330 的回复:楼主 ，是这样一回事，你既然说道父子进程，想必你也知道进程树吧，正常情况下，shell里启动的进程属于shell的子进程(子树)归shell管，如果shell进程结束，一般情况下，它里面启动的所有进程也会结束，但是我记得有一个快捷键，能让进程进入后台守护进程状态，也就是说，脱离shell的控制，变成孤立进程，这个时候，进程会自动被linux 0号进程接管，除此之外还有几种方法。 方法有以下几种： 1、在命令后加一个&，将其放入作业队列,，方法是:  $     ./wireshark &   2、就是我说的，启动进程后，首先按ctrl+z暂停已经运行的进程，然后使用bg命令将停止的作业放到后台运行    但是这些方法也有个问题，那就是父进程目前还是没有任何变动，后台执行的进程，其父进程还是当前终端shell的进程，而一旦父进程退出，则会发送hangup信号给所有子进程，子进程收到hangup以后也会退出。如果我们要在退出shell的时候继续运行进程，则需要使用nohup忽略hangup信号。使用如下代码  $    ./wireshark $    <ctrl+z> $    nohup ./wireshark &    以上回答如有错误，请楼下指出。  $    ./wireshark $    <ctrl+z> $     pg <ctrl+z>时显示的暂停的进程的作业ID $    nohup ./wireshark &  抱歉，我打错了，第二个方法代码还得把暂停的进程转后台执行

第一个问题  是运行环境退出了 ，说以wireshark就退出了   单独点击快捷方式是可以独立运行的

你的wireshark没有后台运行吧~

引用 9 楼 adlay 的回复:[quote=引用 8 楼 caddor9100 的回复:] [quote=引用 6 楼 adlay 的回复:] 你起的进程不是因为父进程死了而死的，而是因为它所依赖的会话终端没有了而死的。所以 UNIX 下的 Daemon 进程都有一个脱离终端的步骤才能让一直存在。  在桌面双击一个程序呢？  这有会话？  桌面里可以不需要运行终端啊 [/quote]  当然，桌面也是一个会话。 http://baike.baidu.com/view/2879217.htm[/quote] 从桌面启动的程序，如果这个桌面会话终止了，那些程序也会终止（如果他们没有脱离的话）

引用 8 楼 caddor9100 的回复:[quote=引用 6 楼 adlay 的回复:] 你起的进程不是因为父进程死了而死的，而是因为它所依赖的会话终端没有了而死的。所以 UNIX 下的 Daemon 进程都有一个脱离终端的步骤才能让一直存在。  在桌面双击一个程序呢？  这有会话？  桌面里可以不需要运行终端啊 [/quote]  当然，桌面也是一个会话。 http://baike.baidu.com/view/2879217.htm

nohup ./wireshark &

父进程死 子进程也得死，当然有这么干的  第二个问题，在

第三个问题看mib2c的帮助文档。


Question: c问题求解

看样子，楼主的str[j]是单个字符吧 strcat函数 char * strcat(char * restrict s1, const char * restrict s2); 功能是把s2拷贝到s1的后面接成一个长的字符串 返回的是s1 这个函数要求s1必须有足够大的空间  c2664错误

strcat是把参数2代表的字符串拼接到参数1代表的字符串的尾部，两个参数要求的是char*类型，而你的str[j]是一个数组元素，也就是char型，所以报错

你需要把str和str1的定义告诉大家，这样才能更好地帮你解决这个问题~目前，但从提示来讲，这个是类型不匹配的问题~

strcat函数的两个参数要求是char*类型，也就是字符指针类型，需要的是地址不是具体的值


Question: 为什么我写的这个程序在VC++中运行时会出现exe已停止工作？求大神助攻！

引用 1 楼 user-4 的回复:void Traverse_list(pNODE pHead) { pNODE p = pHead->pNext; while(NULL != pHead->pNext)  --------------> 改成  while(NULL != p)  +1

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

while(NULL != pHead->pNext) { printf("%d \t",p->data); p = p->pNext;  }这儿时死循环了，需要做一下修改，改成 while (NULL != p)


Question: char在函数中不能返回，已返回程序就报错，麻烦哪位大神来解释下！！

应该是%c。

printf("%c\n",a);

printf("%s\n",a); 改成printf("%c\n",a);

自己做一楼顶起


Question: 谁能帮我看看代码哪错了

同意3楼，7.2f写错位置了。再加个return 0；就ok了。

printf("carea=%7.2f,volume=%7.2f\n",carea,volume); 第一个7.2写错位置了

加了返回值也还是有问题啊，carea的值怎么改都是错的，一定是哪里有错  引用 1 楼 fengxuxing 的回复:没有返回值，其它的没问题吧

没有返回值，其它的没问题吧


Question: 字符串匹配问题

问题解决了，谢谢大家！          regex_t reg;         int cflags=REG_EXTENDED;         const char *pattern="^Session establishment rate";          regmatch_t pmatch[1];         const size_t nmatch=1;          ret=regcomp(®,pattern,cflags);          ret=regexec(®,readbuf,nmatch,pmatch,0);

strsep函数判断吧；用strsep以空格为基准然后分割字符串，然后是用strncmp判断吧~

\s*(\w+) Session

提醒：正则表达式不是万能的；而有限状态自动机是万能的。 仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %32[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8


Question: 无法将字符数组保存到字符串数组中？？

static char data[100][100];//在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。  注意不要越界  注意字符串最后要加'\0'

引用 3 楼 zhao4zhong1 的回复:char data[100][10]; 改为 char data[100][30]; data[1]为 cfg=system，其中“cfg=system”的长度为10个字节＋末尾还需要一个'\0'共11个字节，但前面定义是char data[100][10];，即data[1]中最多保存10个字节。企图将"cfg=system"保存在data[1]中越界了。 我设置data[100][26]后输出有乱码，这是什么原因？另外数组不能设的太大，我设成30就出错，26就可以。

引用 1 楼 zhao4zhong1 的回复:char *data[100]={0}; 改为 char data[100][10];  data[i]=p; 改为 strncpy(data[i],p,9);data[i][9]=0; 1. 再将.c文件编译成可执行文件时提示：warning:passing argument 1 of 'strncpy' form incompatible pointer type.没什么错误，是不死可以忽略？还有一个问题是用sscanf函数引起的:  //data[0]为 method=get sscanf(data[0],"method=%s",f_method); printf("%s",f_method);  //输出正常  //data[1]为 cfg=system  ,这个就出错了 sscanf(data[1],"cfg=%s",f_cfg); printf("%s",f_cfg);  这是为什么？？赵老师麻烦你了。。。


Question: Unhandled Exception 弹出窗口报错

引用 7 楼 sandshaw 的回复:目测会出现while 陷入死循环, 并没有真正的break出去. iLength[iCount] 越界 为什么没能在越界之前break出去？这种问题该怎么解决？

跳过空白的判断是什么?

有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

引用 3 楼 zhao4zhong1 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 堆栈里只有一行，就是帖子中最后一张图片。汇编码里指向了一个将ecx寄存器的数据传递到iLength的dword的mov操作，但我不知道这代表什么，该怎么做

引用 1 楼 user-3 的回复:目测数组访问越界， 100就够了么 的确不是个好办法，但换成1000也还是同样的问题

目测数组访问越界， 100就够了么


Question: 一个helloworld的问题

引用 9 楼 qq_20623897 的回复:[quote=引用 5 楼 tafengtianya 的回复:] 主函数里的多个{}表示变量作用域，在{}里，如果变量前面有类型如int,相当于新声明了一个变量，但其作用域仅限于该{}内，出了{}就不能作用了，最后一个printf输出的是你一开始就声明的变量score，楼主如果还不懂可以F10单步注意观察变量的值变化  对吗[/quote] 好的谢谢

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

其实花括号就二次局部了，懂不

最后一个printf是输出  score = a + 250;但如果int   score = a + 250;   那么最后一个print输出的值就是120 ，你要注意  下面这个score=10是在  int score = 50; 这个作用域的  {         int score = 50;                           //这个score的作用域是下面的大括号         {             score = 10;                                   // 由50变成10             printf("%d\n", score);                      //输出10，换行         }         a = 10;                                       //a的值由20变为10     }      建议楼主还是自己单步运行，F10是单步运行，F11是进入函数内部

引用 5 楼 tafengtianya 的回复:主函数里的多个{}表示变量作用域，在{}里，如果变量前面有类型如int,相当于新声明了一个变量，但其作用域仅限于该{}内，出了{}就不能作用了，最后一个printf输出的是你一开始就声明的变量score，楼主如果还不懂可以F10单步注意观察变量的值变化  对吗

引用 4 楼 qq_20623897 的回复:{}是什么意思？像是java的代码块吗？ 新学C语言 很多地方不懂 为什么最后一句printf 会输出260 而不是30或者130 {} 有特定的意义吗？ 能不能解答一下  对吗

也就是说 最后一个printf是输出的  score = a + 250;   这一段代码  虽然他在变量作用域中 但是没有int 所以能在main方法中引用 如果int   score = a + 250;   那么最后一个print输出的值就是10 对吗

good job

nice to read

#include <stdio.h>  int main() {     int a = 20;     int score = a + 100;     printf("%d\n", score);                        //输出120，换行          {         int score = 50;                           //这个score的作用域是下面的大括号         {             score = 10;                                   // 由50变成10             printf("%d\n", score);                      //输出10，换行         }         a = 10;                                       //a的值由20变为10     }          {         score = a + 250;                          //第一个声明的score变为260         int score = 30;                            //声明score，注意下面的printf输出就是这个score的值         printf("%d", score);                         //输出30，没有换行     }          printf("%d\n", score);                            // 输出260，也即最后一行显示的是30260     return 0; }


Question: unix本地套接字是毛东西？

lsof |grep 'local socket'  查找。试试。

引用 3 楼 caddor9100 的回复:[quote=引用 1 楼 lgbxyz 的回复:] UNIX socket是用来进程间通信的,2  3指的是当前被引用(使用)数, 21380 指的是I-Node 跟文件系统相关,网上一大堆资料自己搜一下  2743/smbd  就是-p结果 PID/进程名 []中间的是flag, 常见的是[ACC] SO_ACCEPTON 显示为ACC,SO_WAITDATA 显示为W,SO_NOSPACE 显示为N.    再具体的你网上搜一下netstat命令 或者 man netstat都很详细的 引用 2 楼 iyomumx 的回复:man netstat 引用   活动的UNIX域套接字    Proto        套接字所用的协议(通常是unix)。     RefCnt        使用数量(也就是通过此套接字连接的进程数)。     Flags        显示的标志为SO_ACCEPTON(显示为           ACC),           SO_WAITDATA           (W)           或           SO_NOSPACE            (N)。        如果相应的进程等待一个连接请求，那么SO_ACCECPTON用于未连接的套接字。其它标志通常并不重要     Type        套接字使用的一些类型：         SOCK_DGRAM               此套接字用于数据报(无连接)模式。         SOCK_STREAM               流模式(连接)套接字         SOCK_RAW               此套接字用于RAW模式。         SOCK_RDM               一种服务可靠性传递信息。         SOCK_SEQPACKET               连续分组套接字。         SOCK_PACKET               RAW接口使用套接字。         UNKNOWN               将来谁知道它的话将告诉我们，就填在这里 :-)     State        此字段包含以下关键字之一：        FREE   套接字未分配。         LISTENING               套接字正在监听一个连接请求。除非设置 --listening (-l) 或者 --all (-a) 选项，否则不显示。         CONNECTING               套接字正要建立连接。         CONNECTED               套接字已连接。         DISCONNECTING               套接字已断开。         (empty)               套接字未连。         UNKNOWN               ！不应当出现这种状态的。     PID/Program name        处理此套接字的程序进程名和PID。上面关于活动的Internet连接的部分有更详细的信息。     Path        当相应进程连入套接字时显示路径名。 [root@localhost ~]# netstat -apn | grep myproc tcp        0      0 0.0.0.0:3344                0.0.0.0:*                   LISTEN      3575/./myproc      tcp        0      0 127.0.0.1:3344              127.0.0.1:52904             ESTABLISHED 3575/./myproc      unix  2      [ ACC ]     STREAM     LISTENING     43970  3575/./myproc     aServer unix  2      [ ACC ]     STREAM     LISTENING     43964  3575/./myproc     /tmp/Dtp unix  2      [ ACC ]     STREAM     LISTENING     43968  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     45162  3575/./myproc      unix  3      [ ]         STREAM     CONNECTED     44358  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     44359  3575/./myproc     aServer  能帮忙结合一个实战分析一下吗？    [root@localhost ~]# netstat -apn | grep myproc tcp        0      0 0.0.0.0:3344                0.0.0.0:*                   LISTEN      3575/./myproc      tcp        0      0 127.0.0.1:3344              127.0.0.1:52904             ESTABLISHED 3575/./myproc      unix  2      [ ACC ]     STREAM     LISTENING     43970  3575/./myproc     aServer unix  2      [ ACC ]     STREAM     LISTENING     43964  3575/./myproc     /tmp/Dtp unix  2      [ ACC ]     STREAM     LISTENING     43968  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     45162  3575/./myproc      unix  3      [ ]         STREAM     CONNECTED     44358  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     44359  3575/./myproc     aServer    myproc  这个程序，我知道它有2中socket方式，一种是本地，一种是tcp. tcp: 3344。  所以有了listen :3344 。 由于程序采用了2中套接字方式，所以有了52904口和它连接。 这我都理解。   不懂的是，从第3行unix 2到最后一行的unix 3。   unix  2      [ ACC ]     STREAM     LISTENING     43970  3575/./myproc     aServer unix  3      [ ]         STREAM     CONNECTED     44359  3575/./myproc     aServer   按照你们的逻辑， aServer是一个路径，所以我搜索看有没有这个文件，结果真搜索到了了这个文件，其权限为： srwxr-xr-x  这个文件的时间变化为： 每次开启 myproc等一系列程序的时候，这个文件就变更。可以得出结论：  aServer是一个 文件，而且是通信用的，之所以没有完整路路径，原因是： 其位置和myproc在同一个目录。  以上是我自己的分析。   我的问题：  aServer 有2行：为什么一个的flags是acc ，一个为空，这不是重点。重点是：  为什么一个的引用数目是2 ，一个是3？     同理：/tmp/this_unix_path 也是如此， 为什么一个是2，另一个是3 ？ unix  2      [ ACC ]     STREAM     LISTENING     43968  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     44358  3575/./myproc     /tmp/this_unix_path   3是代表有3个进程？如果真是3个进程，那么我该如何 找出这2个进程名字？    [/quote]   如何查找进程？ 我已经有方法了，用lsof 方法去查找。

引用 1 楼 lgbxyz 的回复:UNIX socket是用来进程间通信的,2  3指的是当前被引用(使用)数, 21380 指的是I-Node 跟文件系统相关,网上一大堆资料自己搜一下  2743/smbd  就是-p结果 PID/进程名 []中间的是flag, 常见的是[ACC] SO_ACCEPTON 显示为ACC,SO_WAITDATA 显示为W,SO_NOSPACE 显示为N.    再具体的你网上搜一下netstat命令 或者 man netstat都很详细的 引用 2 楼 iyomumx 的回复:man netstat 引用   活动的UNIX域套接字    Proto        套接字所用的协议(通常是unix)。     RefCnt        使用数量(也就是通过此套接字连接的进程数)。     Flags        显示的标志为SO_ACCEPTON(显示为           ACC),           SO_WAITDATA           (W)           或           SO_NOSPACE            (N)。        如果相应的进程等待一个连接请求，那么SO_ACCECPTON用于未连接的套接字。其它标志通常并不重要     Type        套接字使用的一些类型：         SOCK_DGRAM               此套接字用于数据报(无连接)模式。         SOCK_STREAM               流模式(连接)套接字         SOCK_RAW               此套接字用于RAW模式。         SOCK_RDM               一种服务可靠性传递信息。         SOCK_SEQPACKET               连续分组套接字。         SOCK_PACKET               RAW接口使用套接字。         UNKNOWN               将来谁知道它的话将告诉我们，就填在这里 :-)     State        此字段包含以下关键字之一：        FREE   套接字未分配。         LISTENING               套接字正在监听一个连接请求。除非设置 --listening (-l) 或者 --all (-a) 选项，否则不显示。         CONNECTING               套接字正要建立连接。         CONNECTED               套接字已连接。         DISCONNECTING               套接字已断开。         (empty)               套接字未连。         UNKNOWN               ！不应当出现这种状态的。     PID/Program name        处理此套接字的程序进程名和PID。上面关于活动的Internet连接的部分有更详细的信息。     Path        当相应进程连入套接字时显示路径名。 [root@localhost ~]# netstat -apn | grep myproc tcp        0      0 0.0.0.0:3344                0.0.0.0:*                   LISTEN      3575/./myproc      tcp        0      0 127.0.0.1:3344              127.0.0.1:52904             ESTABLISHED 3575/./myproc      unix  2      [ ACC ]     STREAM     LISTENING     43970  3575/./myproc     aServer unix  2      [ ACC ]     STREAM     LISTENING     43964  3575/./myproc     /tmp/Dtp unix  2      [ ACC ]     STREAM     LISTENING     43968  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     45162  3575/./myproc      unix  3      [ ]         STREAM     CONNECTED     44358  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     44359  3575/./myproc     aServer  能帮忙结合一个实战分析一下吗？    [root@localhost ~]# netstat -apn | grep myproc tcp        0      0 0.0.0.0:3344                0.0.0.0:*                   LISTEN      3575/./myproc      tcp        0      0 127.0.0.1:3344              127.0.0.1:52904             ESTABLISHED 3575/./myproc      unix  2      [ ACC ]     STREAM     LISTENING     43970  3575/./myproc     aServer unix  2      [ ACC ]     STREAM     LISTENING     43964  3575/./myproc     /tmp/Dtp unix  2      [ ACC ]     STREAM     LISTENING     43968  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     45162  3575/./myproc      unix  3      [ ]         STREAM     CONNECTED     44358  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     44359  3575/./myproc     aServer    myproc  这个程序，我知道它有2中socket方式，一种是本地，一种是tcp. tcp: 3344。  所以有了listen :3344 。 由于程序采用了2中套接字方式，所以有了52904口和它连接。 这我都理解。   不懂的是，从第3行unix 2到最后一行的unix 3。   unix  2      [ ACC ]     STREAM     LISTENING     43970  3575/./myproc     aServer unix  3      [ ]         STREAM     CONNECTED     44359  3575/./myproc     aServer   按照你们的逻辑， aServer是一个路径，所以我搜索看有没有这个文件，结果真搜索到了了这个文件，其权限为： srwxr-xr-x  这个文件的时间变化为： 每次开启 myproc等一系列程序的时候，这个文件就变更。可以得出结论：  aServer是一个 文件，而且是通信用的，之所以没有完整路路径，原因是： 其位置和myproc在同一个目录。  以上是我自己的分析。   我的问题：  aServer 有2行：为什么一个的flags是acc ，一个为空，这不是重点。重点是：  为什么一个的引用数目是2 ，一个是3？     同理：/tmp/this_unix_path 也是如此， 为什么一个是2，另一个是3 ？ unix  2      [ ACC ]     STREAM     LISTENING     43968  3575/./myproc     /tmp/this_unix_path unix  3      [ ]         STREAM     CONNECTED     44358  3575/./myproc     /tmp/this_unix_path   3是代表有3个进程？如果真是3个进程，那么我该如何 找出这2个进程名字？


Question: c语言socket通讯 服务端问题

给你写个服务器多客户多线程通讯的方式： while（true）{     socket=accept();     分配一个线程：如  new 线程名(socket); } 然后将事件交给线程来处理就行了

不要死板硬套，换个思路，用UDP做多线程，这样就行了

_beginthreadex(NULL, 0, recv2, NULL, NULL, &tid); 这个是用来recv() 的就是一个线程recv() 一个客户端 全部代码：  #include<stdio.h> #include<winsock2.h> #include<conio.h> #include <process.h> #include<windows.h> #pragma comment(lib, "ws2_32.lib")  unsigned tid; sockaddr_in addr; char buf[1024]={0}; SOCKET nes; SOCKET s; SOCKET c1; SOCKET c2; SOCKET c3; SOCKET c4; SOCKET c5;  unsigned WINAPI recv1(PVOID pvParam) { 	while(1) 	{ 		puts("c1进入:"); 		recv(c1,buf,sizeof(buf),0); 		puts(buf); 	} 	return 0; }  unsigned WINAPI recv2(PVOID pvParam) { 	while(1) 	{ 		puts("c2进入:"); 		recv(c2,buf,sizeof(buf),0); 		puts(buf); 	} 	return 0; }  unsigned WINAPI recv3(PVOID pvParam) { 	while(1) 	{ 		puts("c3进入:"); 		recv(c3,buf,sizeof(buf),0); 		puts(buf); 	} 	return 0; }  unsigned WINAPI recv4(PVOID pvParam) { 	while(1) 	{ 		puts("c4进入:"); 		recv(c4,buf,sizeof(buf),0); 		puts(buf); 	} 	return 0; }  unsigned WINAPI recv5(PVOID pvParam) { 	while(1) 	{ 		puts("c5进入:"); 		recv(c5,buf,sizeof(buf),0); 		puts(buf); 	} 	return 0; }   int main() { 	WSADATA wsaData; 	WSAStartup( MAKEWORD(2,2), &wsaData ); 	 	s=socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); 	addr.sin_family = AF_INET;     addr.sin_addr.s_addr = inet_addr( "127.0.0.1" );     addr.sin_port = htons(8000);  	bind( s, (sockaddr*) &addr, sizeof(addr)); 	puts("1"); 	listen( s, 5 );           	puts("5"); 	while(1) 	{ 		puts("6"); 			c1=accept( s, (sockaddr*) &addr, NULL ); 			if(SOCKET_ERROR != c1) 			 { 				puts("2"); 				_beginthreadex(NULL, 0, recv1, NULL, NULL, &tid); 			 } 			c2=accept( s, (sockaddr*) &addr, NULL ); 			if(SOCKET_ERROR != c2) 			 { 				 puts("2"); 				_beginthreadex(NULL, 0, recv2, NULL, NULL, &tid); 			 } 			c3=accept( s, (sockaddr*) &addr, NULL ); 			if(SOCKET_ERROR != c3) 			 { 				 puts("2"); 				_beginthreadex(NULL, 0, recv3, NULL, NULL, &tid); 			 } 			c4=accept( s, (sockaddr*) &addr, NULL ); 			if(SOCKET_ERROR != c4) 			 { 				 puts("2"); 				_beginthreadex(NULL, 0, recv4, NULL, NULL, &tid); 			 } 			c5=accept( s, (sockaddr*) &addr, NULL ); 			if(SOCKET_ERROR != c5) 			 { 				 puts("2"); 				_beginthreadex(NULL, 0, recv5, NULL, NULL, &tid); 			 } 	 	} 	/*_beginthreadex(NULL, 0, recvv, NULL, NULL, &tid);*/ 	getch(); 	return 8; }

所有的链接都用上面代码不区分，把文件描述符传递给新建线程

引用 2 楼 lgbxyz 的回复:服务端 要么迭代，要么并发的，并发的方法是多进程（接受一个请求就创建一个新进程处理这个请求）或者多线程（接受一个请求就创建一个新线程处理这个请求），或者是线程池进程池。  你的做法就是多线程，但是重复写6次accept肯定是不好的,下面这样就能不限制连接数，但是超过最大线程数不行   while(1)  {              c1 = accept( s, (sockaddr*) &addr, NULL );             if(SOCKET_ERROR != c1)              {                 _beginthreadex(NULL, 0, recv1, NULL, NULL, (PVOID)c1);              } }  链接一个客户端就要用一个套接字吗？

先看一下网络编程的基础概念


Question: 如何利用c语言，远程进行xml的读取

引用 9 楼 goldenhawking 的回复:我在学校教书，有意思，拿你的问题今天问了学生，学生回答： 1、先设置一个windows共享文件夹 2、在客户端上用 文件名\\192.168.1.22\xml\1.xml  fopen文件 3、fgets一行printf一行， 你看，完成了“远程”、“读取” 又不用解析。即使是解析，如果只要一两个元素，不如直接 strstr  搜索完了。 我给他打80分。  我在学校教书，有意思，拿你的问题今天问了学生，学生回答： 1、先在电脑\\192.168.1.22上设置一个windows共享文件夹d:\xml，共享名为xml，用命令：net share xml=d:\xml 2、在客户端上用命令net use z: \\192.168.1.22\xml password映射网络驱动器z:到\\192.168.1.22\xml，password为xml共享用户的密码，guest用户可以没密码 3、在C语言中 fopen("z:\\1.xml",...)文件fgets一行printf一行， 4、用完后，在客户端上net use z: /DELETE，在电脑\\192.168.1.22上net share xml /delete 你看，完成了“远程”、“读取” 又不用解析。即使是解析，如果只要一两个元素，不如直接 strstr  搜索完了。 我给他打100分。

~那台计算机远么，近的话走过去看，，远的话打车，，，

的确，只能告诉你相关的知识点，具体怎么操作还是要靠你自己的。而且网上有很多的例子代码，这个不复杂的。

学习了。这个没有用过

还是你自己研究吧 ，我看这帮人回复的也帮不了你

两部分实现：首先是对XML文件进行读取，需要libxml2库，因为这个库会提供解析XML文件的函数接口；然后，读取的内容远程传输即使用socket；C/S架构~

我觉得对你来说很难啊, 你先学socket通信吧, 之后再看是使用什么协议进行下载

引用 1 楼 lgbxyz 的回复:远程：用socket通信进行xml文件传输，获取文件后使用libxml2等xml解析库进行解析 谢谢，但自己不懂，这个操作起来难吗，具体怎么弄呢。

1、远程：socket通信 2、xml处理：网络上有c的xml处理库


Question: printf("%lld %d")和printf("%d %lld")打印结果不一样

我终于好像搞明白第一个问题了   printf("%d, %lld\n", LLONG_MAX, LLONG_MAX); //-1, -2147483649   LLONG_MAX =  a: 1111 1111 ........  1111 1111 (低位4个字节)32个1 b:  0111 1111...........1111 1111  (高位4个字节)0和31个1 c:  1111 1111 ........  1111 1111  d:  0111 1111...........1111 1111  ( LLONG_MAX, LLONG_MAX) 的值分别对应(ba, dc)  printf("%d, %lld")的意思是先取4个字节给%d, 再取8个字节给%lld, 也就是a给了%d, cb给了%lld, 而a就是-1补码,cb就是-2147483649的补码=-1-(2147483648=2^-31)  至于第二个问题,难道%f也是对应8个字节???

//windows #include <limits.h> #include <float.h> #include <stdio.h>  /* #define LLONG_MAX    9223372036854775807i64		    maximum signed long long int value #define FLT_MAX      3.402823466e+38F			    max value  #define LDBL_MAX     1.7976931348623158e+308		max value */  int main(void) { 	printf("%lld, %d\n", LLONG_MAX, LLONG_MAX); 	printf("%d, %lld\n", LLONG_MAX, LLONG_MAX);  	//只要%d打印LLONG_MAX，后续值的打印都会出错，这应该与printf的实现有关 	printf("%lld, %d, %d\n", LLONG_MAX, LLONG_MAX, 1); //9223372036854775807, -1, 2147483647 	printf("%d, %lld, %d\n", LLONG_MAX, LLONG_MAX, 1); //-1, -2147483649, 2147483647  	printf("\n\n"); 	 	//估计还是跟prinf有关，坐等大神 或者 字节研究一下 printf的实现 	printf("%f\n", FLT_MAX); //340282346638528860000000000000000000000.000000 	printf("%f\n", LDBL_MAX);	/* 	17976931348623157000000000000000000000000000000000000000000000000000000000000000 		00000000000000000000000000000000000000000000000000000000000000000000000000000000 		00000000000000000000000000000000000000000000000000000000000000000000000000000000 		000000000000000000000000000000000000000000000000000000000000000000000.000000 */ 	return 0; }

第二个问题,百度到这的回答: scanf()语句："%lf"用于double类型，"%f"用于float类型 printf()语句："%f"用于double类型 double和long double 都是8个字节没影响的输出  后来在pdf中找到这样一句: 浮点型参数的转换   有用于打印double和long double的转换说明符, 但没有用于float的说明符,原因是在K&R C中float的值在被用于表达式中或参数之前,会被自动转换为double类型.


Question: 求帮忙改个c程序 拜托了

#include<time.h> #include<stdio.h>  #include<conio.h>  #include <stdlib.h>   #define MAX 50  void prudctInfo(); void sort(); void prudctgoto(); void prudctinsert(); void prudctdelete(); void prudctupdate(); void average();  int now_no = 0; struct student { 	int no; 	char name[20]; 	int zong; 	float jin; 	float chu; 	int chuliang; 	float sort; 	int kucun; 	float xiaoshousum; 	float jingliave; }; struct student stu[MAX], *p; int main(void) { 	char as = 0;  start:  	printf("\t\t\t\t超市商品管理系统\n\n");  	do { 		printf("\n\t\t\t\t1.商品详细\n\t\t\t\t2.商品买卖\n\t\t\t\t3.库存商品登陆\n\t\t\t\t4.库存商品删除\n\t\t\t\t5.库存商品修改\n\t\t\t\t6.退出\n"); 		printf("\t\t\t\t选择功能选项: "); 		as = getchar(); 		switch (as) 		{ 		case '1': 			system("cls"); 			prudctInfo(); 			break; 		case '2': 			system("cls"); 			prudctgoto(); 			break; 			break; 		case '3': 			system("cls"); 			prudctinsert(); 			break; 		case '4': 			system("cls"); 			prudctdelete(); 			break; 		case '5': 			system("cls"); 			prudctupdate(); 			break; 		case '6': 			system("exit"); 			exit(0); 		default: 			system("cls"); 			goto start; 		} 	} while (1); } void prudctInfo() { 	int i; 	char as; 	float ave; 	do 	{ 		printf("\t\t商品详细\n"); 		printf("\t编号\t商品名\t库存\t单价\t销售数\t销售额\t净利润\n"); 		for (i = 0; i<now_no; i++) 		{ 			stu[i].kucun = stu[i].zong - stu[i].chuliang; 			stu[i].xiaoshousum = stu[i].chu*stu[i].chuliang; 			stu[i].jingliave = stu[i].chu*(stu[i].chu - stu[i].jin); 			printf("\t%d \t%s \t%d \t%.2f\t%d\t%.2f\t%.2f\n", 				stu[i].no, stu[i].name, stu[i].kucun, stu[i].chu, stu[i].chuliang, stu[i].xiaoshousum, stu[i].jingliave); 		} 		printf("\t\t按任意键返回主菜单."); 		as = getch(); 		goto exit; 	} while (as != 'n'); exit: system("cls"); } void prudctgoto() { 	int i = 0; 	char ch; 	int numberID = 0; 	int geshu = 0; 	int a = 0; 	do 	{ 		printf("\t\t商品一览\n"); 		printf("\t编号\t商品名\t库存\t单价\n"); 		for (i = 0; i<now_no; i++) 		{ 			stu[i].kucun = stu[i].zong - stu[i].chuliang; 			printf("\t%d \t%s \t%d \t%.2f\n", 				stu[i].no, stu[i].name, stu[i].kucun, stu[i].chu); 		} 		a = -1; 		printf("\n商品编号:"); 		scanf("%d", &numberID); 		for (i = 0; i<now_no; i++) 		{ 			if (stu[i].no == numberID){ 				a = i; 			} 		} 		if (a == -1){ 			printf("没这个商品!"); 			ch = getch(); 			system("cls"); 		} 		else{ 			printf("\n卖出个数:"); 			scanf("%d", &geshu); 			if (stu[a].zong<geshu){ 				printf("没这么多商品"); 				ch = getch(); 				system("cls"); 			} 			else{ 				fflush(stdin); 				stu[a].chuliang = geshu; 			} 		} 		printf("是否继续输入?(Y/N)"); 		ch = getch(); 		system("cls"); 	} while (ch != 'n'); 	system("cls"); } void prudctinsert() { 	int i = 0; 	char ch; 	do 	{ 		printf("\t\t\t\t1.输入商品信息\n输入第%d个商品情报\n", i + 1); 		printf("\n登陆商品编号:"); 		scanf("%d", &stu[i].no); 		fflush(stdin); 		printf("\n登陆商品名:"); 		fflush(stdin); 		gets(stu[i].name); 		printf("\n登陆超市进货商品个数:"); 		fflush(stdin); 		scanf("%d", &stu[i].zong); 		printf("\n登陆商品进货单价:"); 		fflush(stdin); 		scanf("%f", &stu[i].jin); 		printf("\n登陆商品售出单价:"); 		fflush(stdin); 		scanf("%f", &stu[i].chu); 		stu[i].chuliang = 0; 		printf("\n\n"); 		i++; 		now_no = i; 		printf("%d", now_no); 		printf("是否继续输入?(Y/N)"); 		ch = getch(); 		system("cls"); 	} while (ch != 'n'); 	system("cls"); } void prudctdelete(){ 	int inum, i, j; 	printf("输入要删除商品编号:"); 	fflush(stdin); 	scanf("%d", &inum); 	for (i = 0; i<now_no; i++) 	{ 		if (stu[i].no == inum) 		{ 			for (j = i; j<now_no; j++) 			{ 				stu[i] = stu[i + 1]; 			} 			now_no = now_no - 1; 		} 		break; 	} 	system("cls"); } void prudctupdate(){ 	char ch; 	do 	{ 		printf("\n\t\t输入新商品信息\n"); 		printf("\n登陆商品编号:"); 		scanf("%d", &stu[now_no].no); 		fflush(stdin); printf("\n登陆商品名:"); 		fflush(stdin); 		gets(stu[now_no].name); 		printf("\n登陆超市进货商品个数:"); 		fflush(stdin); 		scanf("%d", &stu[now_no].zong); 		printf("\n登陆商品进货单价:"); 		fflush(stdin); 		scanf("%f", &stu[now_no].jin); 		printf("\n登陆商品售出单价:"); 		fflush(stdin); 		scanf("%f", &stu[now_no].chu); 		printf("\n登陆超市商品卖去个数:"); 		fflush(stdin); 		scanf("%d", &stu[now_no].chuliang); 		printf("\n\n"); 		now_no = now_no + 1; 		printf("是否继续输入?(Y/N)"); 		ch = getch(); 		system("cls"); 	} while (ch != 'n'); } void sort() { 	struct student temp; 	int i, j; 	for (i = 1; i<now_no; i++) 	{ 		for (j = 1; j <= now_no - i; j++) 		{ 			if (stu[j - 1].jingliave<stu[j].jingliave) 			{ 				temp = stu[j]; 				stu[j] = stu[j - 1]; 				stu[j - 1] = temp; 			} 		} 	} }


Question: 定义字符指针数组char *str[5]分别指向5 个字符串常量，从小到大输出字符串的内容。

这个程序把 for(i=0; i<5; i++)         {             printf("%s\n", str[i]);         }  放到return 0；前面即可。

使用strcmp,strlen是比较长度的,随便选择一个排序方法,其它的都是基本语句,比较基础.

你整个程序的功能相当于先找到最短字符串的位置，然后将他记录，再与第一个字符串交换位置，然后 i 的值变为 5 ，外面的for循环相当于没有

你的程序只比较了一遍，i就变成5跳出整个循环了。把输出语句放到return前面。

引用 3 楼 wangxingguo1994 的回复:你这个程序问题多啊，我给你撸一遍逻辑：首先i=0，min=i=0，从j=1开始，到j=4，找出了最小的字符串s和最长的交换位置，然后现在字符串第一个为s，第三个为最长的字符串，其他的位置不变，然后你就循环输出了。 再然后用i=1，min=1，j=2开始，到j=4找剩下比第二个字符串短的字符串，可惜第二个字符串刚好就是第二短的，所以位置不变，然后又原封不动的循环输出了一边。所以你应该最后输出了5组25行吧。     for(i=0; i<5-1; i++)     {         ......         for(i=0; i<5; i++)         {             printf("%s\n", str[i]);         }               // 里外两个循环，用的是同一个i。printf的小循环结束的时候，i的值是5，所以外边的大循环就会马上结束了，不会输出5组25行     }

手机打字不太方便，就第二次循环查找最小字符串说错了。你把树上的冒泡法再好好看看，注意输出的放置位置

printf的循环放错位置了。把他拿到最后，紧挨着retun 0

比较大小为什么不用strcmp？