C 程序在 linux 和 windows 上编译时没有相同的结果
C Program don't have the same result when compiled on linux and windows
当我用 windows 上的 mingw 和 linux 上的 gcc 编译我的程序时,可执行文件没有给我相同的结果。
此代码应该获取文件并对其进行加密。
但是如果最后一个块未满或者文件小于 32 字节,当我需要添加一些字节时,Linux 会像我想要的那样添加值“0”,但是在 Windows,没用。
顺便说一下,每个的 hexdump 都不相似。
执行它:./encrypt [FileIn] [FileOut] 1 [yourKey] [yourIV]
Key 和 IV 随便放,它们都写在测试代码里面了(我只放了“1”和“1”以免报错)
argv[3] 需要为“1”才能加密
我正在使用一个写有 "toto" 的文件对其进行测试(放任何你想要的东西,但不要超过 32 个字符,因为这是我现在正在测试的)。
调试代码里面的Key和IV是一样的,不会出错
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*FUNCTIONS*/
int encrypt(char* in, char* out, char* key, char* primalIv);
int decrypt(char* in, char* out);
void myprint(char* content, int size);
char* xor(char* data, char* key, int size);
void bitStuffing(char* in, int rem);
/*GLOBAL VARIABLES*/
int errorLevel;
int blockSize = 32; /*Tailles de blocs en octet*/
/*CALL : ./main inFile outFile methode key iv*/
/*FILE STRUC : [datas] [stuffing] [stuffingValue] [iv]*/
int main(int argc, char** argv)
{
/*Support de l'aide à l'utilisateur*/
if(argc == 2 && !strcmp(argv[1],"help"))
{
printf("\nUsage : ./cied [inFile] [outFile] [methode] [key] [iv]\n\n");
printf("[inFile] : Input file to use\n");
printf("[outFile] : Ouput file to use\n");
printf("[methode] : Encrypt (1) or decrypt (0)\n");
printf("[key] : The key to use\n");
printf("[iv] : The initialisation vector.\n");
printf(" (none for decrypt !)\n");
return 0; /*Fermeture gratieuse du programme*/
}
/*Support des erreurs d'arguments*/
if(argc != 5 && argc != 6)
{
printf("[ERR] Args error!\n");
printf("[INF] Enter 'help' to display help\n");
return 1;
}
else if(atoi(argv[3]) == 1 && argc != 6) /*Nombre d'arguments pour chiffrement*/
{
printf("[ERR] Args error : given %d when waiting 5!\n",(argc-1));
printf("[INF] Enter 'help' to display help\n");
return 1;
}
else if(atoi(argv[3]) == 0 && argc != 5)/*Nombre d'arguments pour dechiffrement*/
{
printf("[ERR] Args error : given %d when waiting 4!\n",(argc-1));
printf("[INF] Enter 'help' to display help\n");
return 1;
}
/***Chiffrement et dechiffremet***/
if(atoi(argv[3]) == 1)
{
errorLevel = encrypt(argv[1], argv[2],"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");/*Chiffrement*/
if(!errorLevel)
{
printf("[INF] finished\n");
}
else
{
printf("[ERR] An error as occured.\n");
}
}
else if(atoi(argv[3]) == 0)
{
errorLevel = decrypt(argv[1], argv[2]); /*Dechiffrement*/
if(!errorLevel)
{
printf("[INF] finished\n");
}
else
{
printf("[ERR] An error as occured.\n");
}
}
else
{
printf("[ERR] Wrong method given!");
printf("[INF] Enter 'help' to display help\n");
return 1;
}
return 0;
}
/*FONCTIONS CORE*/
int encrypt(char* in, char* out, char* key, char* primalIv)
{
/*Variables*/
char* block = NULL;
char* xored = NULL;
char* iv = NULL;
int readed;
int inFileSize;
int numOfBlock;
int rem = 0;
int i;
FILE *inFile;
FILE *outFile;
iv = primalIv;
/*Ouverture des fichiers*/
inFile = fopen(in,"rb");
outFile = fopen(out,"w");
/*Gestion des erreurs de fichier*/
if(inFile == NULL)
{
printf("[ERR] Problem reading input file. Please check path and permissions.\n");
}
else if(outFile == NULL)
{
printf("[ERR] Problem reading output file. Please check path and permissions.\n");
}
block = malloc(blockSize);
/*Récupération de la longueur du fichier*/
fseek(inFile, 0, SEEK_END);
inFileSize = ftell(inFile);
rewind(inFile);
/*Calcul du nombre de bloc et du reste*/
numOfBlock = inFileSize / blockSize;
rem = inFileSize % blockSize;
printf("[INF] File will be split in %d block(s). %d will remain.\n",numOfBlock,rem);
if(inFileSize < blockSize)
{
readed = fread(block,1,blockSize,inFile);
printf("[INF] readed %d bytes \n",readed);
/*Bourrage*/
bitStuffing(block,(blockSize-readed));
/*Xor avec l'IV*/
xored = xor(block,iv,blockSize);
/*Xor avec la clé*/
xored = xor(xored,key,blockSize);
/*Sauvegarde du block pour réutilisation en tant qu'IV*/
iv = xored;
/*Ecriture dans le fichier*/
fwrite(xored,1,blockSize,outFile);
}
else
{
for(i=0;i<numOfBlock;i++)
{
printf("qzekonfk le\n");
readed = fread(block,1,blockSize,inFile);
printf("[INF] readed %d bytes \n",readed);
if(readed != blockSize)
{
printf("[WRN] The readed block siez is different than usual !(%d != %d)\n",blockSize,readed);
}
/*Xor avec l'IV*/
printf("IV :\n");
xored = xor(block,iv,readed);
/*Xor avec la clé*/
printf("KEY :\n");
xored = xor(xored,key,readed);
/*Sauvegarde du block pour réutilisation en tant qu'IV*/
iv = xored;
/*Ecriture dans le fichier*/
fwrite(xored,1,readed,outFile);
}
/*Bourrage*/
if(rem)
{
readed = fread(block,1,blockSize,inFile);
printf("[INF] readed %d bytes \n",readed);
/*Bourrage*/
bitStuffing(block,(blockSize-readed));
/*Xor avec l'IV*/
xored = xor(block,iv,readed);
/*Xor avec la clé*/
xored = xor(xored,key,readed);
/*Sauvegarde du block pour réutilisation en tant qu'IV*/
iv = xored;
/*Ecriture dans le fichier*/
fwrite(xored,1,readed,outFile);
}
}
/*Inscription de rem dans le fichier pour préparer le déchiffrement*/
fprintf(outFile, "%c",rem);
/*Inscription de l'IV*/
printf("IV (again):\n");
fwrite(xor(primalIv,key,blockSize),1,blockSize,outFile);
/*Free des malloc*/
free(block);
free(xored);
return 0;
}
int decrypt(char* in, char* out)
{
return 0;
}
/*FONCTIONS UTILITAIRES*/
char* xor(char* data, char* key, int size)
{
int i;
char* result = malloc(size);
for(i=0; i<size; i++)
{
result[i] = data[i] ^ key[i];
printf(" %x ^ %x = %x\n",data[i],key[i],result[i]);
}
return result;
}
void myprint(char* content, int size)
{
int i;
printf(" ");
for(i=0;i<=blockSize;i++)
{
printf(" %x",content[i]);
}
printf("\n");
}
void bitStuffing(char* in, int rem) {
int i;
printf("\nBEGIN STUFFING");
for(i=rem; i<sizeBlock; i++) {
in[i] = 0;
/*printf("%x", in[i]);*/
}
printf("\nEND STUFFING\n");
}
@alk 你是对的,我在阅读你的 post 之前就发现了它。
我的朋友为 bitStuffing() 函数提供了错误的值。他不需要给出空字节数,而是给出循环开始的字节数。然后就是
bitStuffing(block, readed);
而不是
bitStuffing(block, (blockSize-readed));
对于想要少一点代码的每个人,我创建这个基本上是为了填充:
#include <stdio.h>
#include <stdlib.h>
void bitStuffing(char* in, int rem);
void myprint(char* content, int size);
int blockSize = 32;
int main()
{
char* block;
int inFileSize = 4; /*In my example, the file used is a text file containing "toto"*/
int readed;
FILE *outFile;
readed = inFileSize % blockSize; /*Getting the number of bits to stuff*/
block = malloc(blockSize);
block[0] = "t";
block[1] = "o";
block[2] = "t";
block[3] = "o";
bitStuffing(block, readed);
outFile = fopen("C:/Users/Julien/Desktop/text3.txt", "wb");
fwrite(block,1,blockSize,outFile);
fclose(outFile);
return 0;
}
void bitStuffing(char* in, int begin) {
printf("\nBEGIN STUFFING");
printf("\nrem =%2d", begin);
int i;
for(i=begin; i<blockSize; i++) {
in[i] = 0;
printf("\ni =%1d | value =%1x\n ",i, in[i]);
myprint(in, i);
}
printf("\nEND STUFFING\n");
}
void myprint(char* content, int size)
{
int i;
printf("\n");
for(i=0;i<size;i++)
{
printf("%2x",content[i]);
}
printf("\n");
}
这和我想要的一样有效。然后我确定问题不是来自 bitStuffing
谢谢大家
现在,我要扇我朋友一巴掌
当我用 windows 上的 mingw 和 linux 上的 gcc 编译我的程序时,可执行文件没有给我相同的结果。
此代码应该获取文件并对其进行加密。
但是如果最后一个块未满或者文件小于 32 字节,当我需要添加一些字节时,Linux 会像我想要的那样添加值“0”,但是在 Windows,没用。
顺便说一下,每个的 hexdump 都不相似。
执行它:./encrypt [FileIn] [FileOut] 1 [yourKey] [yourIV]
Key 和 IV 随便放,它们都写在测试代码里面了(我只放了“1”和“1”以免报错)
argv[3] 需要为“1”才能加密
我正在使用一个写有 "toto" 的文件对其进行测试(放任何你想要的东西,但不要超过 32 个字符,因为这是我现在正在测试的)。
调试代码里面的Key和IV是一样的,不会出错
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*FUNCTIONS*/
int encrypt(char* in, char* out, char* key, char* primalIv);
int decrypt(char* in, char* out);
void myprint(char* content, int size);
char* xor(char* data, char* key, int size);
void bitStuffing(char* in, int rem);
/*GLOBAL VARIABLES*/
int errorLevel;
int blockSize = 32; /*Tailles de blocs en octet*/
/*CALL : ./main inFile outFile methode key iv*/
/*FILE STRUC : [datas] [stuffing] [stuffingValue] [iv]*/
int main(int argc, char** argv)
{
/*Support de l'aide à l'utilisateur*/
if(argc == 2 && !strcmp(argv[1],"help"))
{
printf("\nUsage : ./cied [inFile] [outFile] [methode] [key] [iv]\n\n");
printf("[inFile] : Input file to use\n");
printf("[outFile] : Ouput file to use\n");
printf("[methode] : Encrypt (1) or decrypt (0)\n");
printf("[key] : The key to use\n");
printf("[iv] : The initialisation vector.\n");
printf(" (none for decrypt !)\n");
return 0; /*Fermeture gratieuse du programme*/
}
/*Support des erreurs d'arguments*/
if(argc != 5 && argc != 6)
{
printf("[ERR] Args error!\n");
printf("[INF] Enter 'help' to display help\n");
return 1;
}
else if(atoi(argv[3]) == 1 && argc != 6) /*Nombre d'arguments pour chiffrement*/
{
printf("[ERR] Args error : given %d when waiting 5!\n",(argc-1));
printf("[INF] Enter 'help' to display help\n");
return 1;
}
else if(atoi(argv[3]) == 0 && argc != 5)/*Nombre d'arguments pour dechiffrement*/
{
printf("[ERR] Args error : given %d when waiting 4!\n",(argc-1));
printf("[INF] Enter 'help' to display help\n");
return 1;
}
/***Chiffrement et dechiffremet***/
if(atoi(argv[3]) == 1)
{
errorLevel = encrypt(argv[1], argv[2],"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");/*Chiffrement*/
if(!errorLevel)
{
printf("[INF] finished\n");
}
else
{
printf("[ERR] An error as occured.\n");
}
}
else if(atoi(argv[3]) == 0)
{
errorLevel = decrypt(argv[1], argv[2]); /*Dechiffrement*/
if(!errorLevel)
{
printf("[INF] finished\n");
}
else
{
printf("[ERR] An error as occured.\n");
}
}
else
{
printf("[ERR] Wrong method given!");
printf("[INF] Enter 'help' to display help\n");
return 1;
}
return 0;
}
/*FONCTIONS CORE*/
int encrypt(char* in, char* out, char* key, char* primalIv)
{
/*Variables*/
char* block = NULL;
char* xored = NULL;
char* iv = NULL;
int readed;
int inFileSize;
int numOfBlock;
int rem = 0;
int i;
FILE *inFile;
FILE *outFile;
iv = primalIv;
/*Ouverture des fichiers*/
inFile = fopen(in,"rb");
outFile = fopen(out,"w");
/*Gestion des erreurs de fichier*/
if(inFile == NULL)
{
printf("[ERR] Problem reading input file. Please check path and permissions.\n");
}
else if(outFile == NULL)
{
printf("[ERR] Problem reading output file. Please check path and permissions.\n");
}
block = malloc(blockSize);
/*Récupération de la longueur du fichier*/
fseek(inFile, 0, SEEK_END);
inFileSize = ftell(inFile);
rewind(inFile);
/*Calcul du nombre de bloc et du reste*/
numOfBlock = inFileSize / blockSize;
rem = inFileSize % blockSize;
printf("[INF] File will be split in %d block(s). %d will remain.\n",numOfBlock,rem);
if(inFileSize < blockSize)
{
readed = fread(block,1,blockSize,inFile);
printf("[INF] readed %d bytes \n",readed);
/*Bourrage*/
bitStuffing(block,(blockSize-readed));
/*Xor avec l'IV*/
xored = xor(block,iv,blockSize);
/*Xor avec la clé*/
xored = xor(xored,key,blockSize);
/*Sauvegarde du block pour réutilisation en tant qu'IV*/
iv = xored;
/*Ecriture dans le fichier*/
fwrite(xored,1,blockSize,outFile);
}
else
{
for(i=0;i<numOfBlock;i++)
{
printf("qzekonfk le\n");
readed = fread(block,1,blockSize,inFile);
printf("[INF] readed %d bytes \n",readed);
if(readed != blockSize)
{
printf("[WRN] The readed block siez is different than usual !(%d != %d)\n",blockSize,readed);
}
/*Xor avec l'IV*/
printf("IV :\n");
xored = xor(block,iv,readed);
/*Xor avec la clé*/
printf("KEY :\n");
xored = xor(xored,key,readed);
/*Sauvegarde du block pour réutilisation en tant qu'IV*/
iv = xored;
/*Ecriture dans le fichier*/
fwrite(xored,1,readed,outFile);
}
/*Bourrage*/
if(rem)
{
readed = fread(block,1,blockSize,inFile);
printf("[INF] readed %d bytes \n",readed);
/*Bourrage*/
bitStuffing(block,(blockSize-readed));
/*Xor avec l'IV*/
xored = xor(block,iv,readed);
/*Xor avec la clé*/
xored = xor(xored,key,readed);
/*Sauvegarde du block pour réutilisation en tant qu'IV*/
iv = xored;
/*Ecriture dans le fichier*/
fwrite(xored,1,readed,outFile);
}
}
/*Inscription de rem dans le fichier pour préparer le déchiffrement*/
fprintf(outFile, "%c",rem);
/*Inscription de l'IV*/
printf("IV (again):\n");
fwrite(xor(primalIv,key,blockSize),1,blockSize,outFile);
/*Free des malloc*/
free(block);
free(xored);
return 0;
}
int decrypt(char* in, char* out)
{
return 0;
}
/*FONCTIONS UTILITAIRES*/
char* xor(char* data, char* key, int size)
{
int i;
char* result = malloc(size);
for(i=0; i<size; i++)
{
result[i] = data[i] ^ key[i];
printf(" %x ^ %x = %x\n",data[i],key[i],result[i]);
}
return result;
}
void myprint(char* content, int size)
{
int i;
printf(" ");
for(i=0;i<=blockSize;i++)
{
printf(" %x",content[i]);
}
printf("\n");
}
void bitStuffing(char* in, int rem) {
int i;
printf("\nBEGIN STUFFING");
for(i=rem; i<sizeBlock; i++) {
in[i] = 0;
/*printf("%x", in[i]);*/
}
printf("\nEND STUFFING\n");
}
@alk 你是对的,我在阅读你的 post 之前就发现了它。 我的朋友为 bitStuffing() 函数提供了错误的值。他不需要给出空字节数,而是给出循环开始的字节数。然后就是
bitStuffing(block, readed);
而不是
bitStuffing(block, (blockSize-readed));
对于想要少一点代码的每个人,我创建这个基本上是为了填充:
#include <stdio.h>
#include <stdlib.h>
void bitStuffing(char* in, int rem);
void myprint(char* content, int size);
int blockSize = 32;
int main()
{
char* block;
int inFileSize = 4; /*In my example, the file used is a text file containing "toto"*/
int readed;
FILE *outFile;
readed = inFileSize % blockSize; /*Getting the number of bits to stuff*/
block = malloc(blockSize);
block[0] = "t";
block[1] = "o";
block[2] = "t";
block[3] = "o";
bitStuffing(block, readed);
outFile = fopen("C:/Users/Julien/Desktop/text3.txt", "wb");
fwrite(block,1,blockSize,outFile);
fclose(outFile);
return 0;
}
void bitStuffing(char* in, int begin) {
printf("\nBEGIN STUFFING");
printf("\nrem =%2d", begin);
int i;
for(i=begin; i<blockSize; i++) {
in[i] = 0;
printf("\ni =%1d | value =%1x\n ",i, in[i]);
myprint(in, i);
}
printf("\nEND STUFFING\n");
}
void myprint(char* content, int size)
{
int i;
printf("\n");
for(i=0;i<size;i++)
{
printf("%2x",content[i]);
}
printf("\n");
}
这和我想要的一样有效。然后我确定问题不是来自 bitStuffing
谢谢大家
现在,我要扇我朋友一巴掌