Last active
February 17, 2016 10:20
-
-
Save alxlion/d4a812e92e270a109fde to your computer and use it in GitHub Desktop.
Correction TP 1GCC - 2015-2016
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdint.h> | |
#define MAX_LENGTH 1024 | |
void convertToBinary(char* word); // Ces prototypes de fonctions (ou signatures) pouvaient | |
void convertToHex(char* word); // très bien se trouver dans un fichier .h et leur implémentation | |
void convertToBase64(char* word); // dans un fichier .c correspondant. | |
int main(int argc, char *argv[]) | |
{ | |
char wordToConvert[MAX_LENGTH]; | |
int base = 0; | |
/* | |
* 1re étape: On commence par définir nos deux premières variables qui vont nous être | |
* utile pour notre programme. | |
*/ | |
/* Pour le mode CLI : ./monProgramme argument1 argument2 | |
* \/ \/ \/ | |
argv[0] argv[1] argv[2] | |
*/ | |
if(argc > 1) { | |
// Première méthode non recommandée, l'utilisateur peut provoquer un buffer overflow: Faille de sécurité ! | |
// wordToConvert = argv[1]; | |
strncpy(wordToConvert, argv[1], MAX_LENGTH); // Meilleure sécurité | |
base = atoi(argv[2]); // On converti notre pointer char (argv[2]) en int pour le stocker dans notre variable base. | |
// Never trust the user input ! | |
if (base != 2 && base != 16 && base != 64) { | |
puts("Wrong base :("); | |
return 1; | |
} | |
} | |
/* Pour le mode STDIN: Lancement du programme sans arguments */ | |
else { | |
puts("Enter a sentence to convert: "); | |
// On utilise fgets() afin de pouvoir stocker les espaces et donc des phrases à partir de l'entrée standard (console) : stdin | |
fgets(wordToConvert, MAX_LENGTH, stdin); | |
puts("Enter the base to convert (2, 16, 64): "); | |
// %d: On attend de l'utilisateur un entier. &base : stockage de la valeur à l'adresse de la variable base ! | |
scanf("%d", &base); | |
} | |
/* Une fois qu'on a nos deux variables, on va pouvoir les utiliser | |
* grâce à nos fonctions (qui pouvaient être dans un autre fichier source). | |
*/ | |
switch(base) { | |
case 2: | |
convertToBinary(wordToConvert); | |
break; | |
case 16: | |
convertToHex(wordToConvert); | |
break; | |
case 64: | |
convertToBase64(wordToConvert); | |
break; | |
// Pas besoin de default car on vérifie avant que la base soit bien 2, 16 ou 64. | |
} | |
return 0; | |
} | |
void convertToBinary(char* word) { | |
/* | |
* On pouvait utiliser la fonction itoa() mais ne faisant pas parti du standard C | |
* il était déconseillé de l'utiliser (certains compilateurs ne l'accepte plus). | |
* Ici, mille et une façon de convertir un binaire, voici la mienne. | |
*/ | |
for(int i = 0; i < strlen(word)-1; i++) { | |
printf("%c%c%c%c%c%c%c%c ", // %c : on veut afficher soit '0' ou '1' qui sont des char | |
// Utilisation des masques pour chaque bit | |
(word[i] & 0b10000000)? '1' : '0', | |
(word[i] & 0b01000000)? '1' : '0', | |
(word[i] & 0b00100000)? '1' : '0', | |
(word[i] & 0b00010000)? '1' : '0', | |
(word[i] & 0b00001000)? '1' : '0', | |
(word[i] & 0b00000100)? '1' : '0', | |
(word[i] & 0b00000010)? '1' : '0', | |
(word[i] & 0b00000001)? '1' : '0' | |
); | |
} | |
printf("\n"); | |
} | |
void convertToHex(char* word) { | |
/* | |
* On utilise ici les avantages du printf() | |
*/ | |
for(int i = 0; i < strlen(word)-1; i++) { | |
printf("%X", word[i]); | |
} | |
printf("\n"); | |
} | |
void convertToBase64(char* word) { | |
/* | |
* L'encodage (et le décodage) en base64 est de loin la fonction la plus évidente et facile à implémenter. | |
* Il n'est pas de votre niveau et demande l'utilisation de certaines bibliothèques (OpenSSL) pour pouvoir l'implémenter | |
* correctement. Ici elle a été implémentée manuellement, elle ne vient pas de moi (http://rosettacode.org/wiki/Base64_encode_data#Manual_implementation). | |
* Le barême sera ajusté en conséquence étant donné ce qui été demandé en seulement 2h. | |
*/ | |
static char base64en[] = { | |
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', | |
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', | |
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', | |
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', | |
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', | |
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', | |
'w', 'x', 'y', 'z', '0', '1', '2', '3', | |
'4', '5', '6', '7', '8', '9', '+', '/', | |
}; | |
int i, j; | |
char out[strlen(word)-1]; | |
for (i = j = 0; i < strlen(word)-1; i++) { | |
int s = i % 3; /* from 6/gcd(6, 8) */ | |
switch (s) { | |
case 0: | |
out[j++] = base64en[(word[i] >> 2) & 0x3F]; | |
continue; | |
case 1: | |
out[j++] = base64en[((word[i-1] & 0x3) << 4) + ((word[i] >> 4) & 0xF)]; | |
continue; | |
case 2: | |
out[j++] = base64en[((word[i-1] & 0xF) << 2) + ((word[i] >> 6) & 0x3)]; | |
out[j++] = base64en[word[i] & 0x3F]; | |
} | |
} | |
/* move back */ | |
i -= 1; | |
/* check the last and add padding */ | |
if ((i % 3) == 0) { | |
out[j++] = base64en[(word[i] & 0x3) << 4]; | |
out[j++] = '='; | |
out[j++] = '='; | |
} else if ((i % 3) == 1) { | |
out[j++] = base64en[(word[i] & 0xF) << 2]; | |
out[j++] = '='; | |
} | |
for(int i = 0; i < strlen(out); i++) { | |
printf("%c", out[i]); | |
} | |
printf("\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment