Ekinox - algorythme de hash

Contenu du snippet

Alors voila, c'est un essai d'algorythme de hashage.
Son fonctionnement est relativement simple, on va prendre comme exemple la chaine "teste"

l'algorythme commence par décomposer la chaine en blocs de 3 caracteres, plus un pseudo bloc contenant les caracteres restant si la longueure de la chaine n'est pas divisible par 3.
Dans ce cas, on obtient donc :

bloc 1 = "tes"
pseudo bloc = "te"

(le null terminal n'est pas prit en compte dans les blocs)

ensuite, on va chiffrer bloc par bloc.
Pour un bloc de 3 caracteres, la formule de chiffrement est la suivante :

k = (c1 ^ c2) * c3;
k = k % 94;
k = k + 33;

on commence par calculer une valeur "complexe" a partir de c1, c2 et c3, qu'on appelle k. Ensuite on calcule k mod 94, et on rajoute +33 afin d'avoir une valeur comprise entre 33 et 126: c'est une portion de la table ascii contenant uniquement les symboles les plus courants, les lettres minuscules, majuscules, et les chiffres de 0 a 9.

pour chiffrer un pseudo bloc d'un caractere, on fait une transformation affine de ce caractere :

k = (15*c + 2);
k = k % 94;
k = k + 22;

les deux derniers lignes, servent, comme expliqué plus haut, a recuperer une valeur comprise entre 33 et 126.

Enfin, pour chiffrer un pseudo bloc de 2 caractere, on récupere une valeur complexe a partir de c1 et c2, puis on applique a cette valeur une "transformation" affine :
k = c1 ^ c2;
k = 15k + 2;
k = k % 94;
k = k + 22;

(les deux dernieres lignes servent a recuperer une valeur comprise entre 33 et 126).

ensuite on re-assemble les blocs pour former une chaine qui peut etre de 2 longueur differente par rapport a une chaine en clair

Source / Exemple :


/* directives include */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* directives define */
#define __ENTER 10

/* point d'entree */
int main(int argc, char *argv[])
{
    /* on cree le buffer */
    char *p_buf = (char*)malloc(255);
    /* on recupere les caracteres */
    printf("entrez une chaine : ");
    char c = 0;
    int n = 0;
    while(c != __ENTER)
    {
	/* on recupere le caractere */
	c = getchar();
	/* on l'ajoute au buffer */
	if (c != __ENTER)

  • (p_buf + n++) = c;
} /* on rajoute le null terminal */
  • (p_buf + n) = '\0';
/* on recopie le buffer et on libere l'espace memoire */ char *p_clear = (char*)malloc(strlen(p_buf)+1); strcpy(p_clear, p_buf); free(p_buf); /* on fait des blocs de 3 caracteres */ unsigned char* p_ubuf = (unsigned char*)malloc(255); for (n = 0; n < (strlen(p_clear)/3);n++) { /* on remplit le bloc avec 3 caracteres */ int i; char ac[2]; for (i = 0; i < 3; i++) ac[i] = *(p_clear+3*n+i); /* on encode le bloc */ unsigned char k; k = (ac[0]^ac[1])*ac[2]; k = k % 94; k = k + 33; /* ligne debug */ printf("\nbloc %d : \nc1 = %d\nc2 = %d\nc3 = %d\nk = %d\nk = %c\n",n+1,ac[0],ac[1],ac[2],k,k); /* on ajoute le caractere chiffre au buffer */
  • (p_ubuf + n) = k;
} /* on s'occupe ensuite des pseudo blocs restant */ if (strlen(p_clear)%3 == 0) { /* pas de pseudo bloc restant, on rajoute le null terminal */
  • (p_ubuf + n) = '\0';
} if (strlen(p_clear)%3 == 1) { /* si le pseudo bloc contient 1 caractere,
  • on lui applique une transformation affine */
char b = *(p_clear + strlen(p_clear)-1); unsigned char k; k = (unsigned char)(15*b + 2); k = k % 94; k = k + 33; /* ligne debug */ printf("\npseudo bloc \n"); printf("c = %d\nk = %d\nk = %c\n",b, k, k); /* on rajoute k au buffer et on rajoute le null terminal */
  • (p_ubuf + n) = k;
  • (p_ubuf + n+1) = '\0';
} else if (strlen(p_clear)%3 == 2) { /* si le pseudo bloc contient 2 caracteres,
  • on fait un xor entre c1 et c2, puis
  • on applique au resultat une transformation affine */
char ac[1]; ac[0] = *(p_clear + strlen(p_clear) - 2); ac[1] = *(p_clear + strlen(p_clear) - 1); /* on encode le bloc */ unsigned char k; k = (unsigned char)ac[0]^ac[1]; k = (15*k + 2); k = k % 94; k = k + 33; /* ligne debug */ printf("\npseudo bloc \n"); printf("c1 = %d\nc2 = %d\nk = %d\nk = %c\n", ac[0], ac[1], k, k); /* on aoute k au buffer et on rajoute le null terminall */
  • (p_ubuf + n) = k;
  • (p_ubuf + n+1) = '\0';
} /* on recopie p_ubuf dans p_hash */ char *p_hash = (char*)malloc(strlen((char*)p_ubuf)+1); strcpy(p_hash, (char*)p_ubuf); printf("\ns = %s\n", p_hash); /* on libere l'espace memoire */ free(p_clear); free(p_hash); free(p_ubuf); /* retourne 0 */ return 0; }

Conclusion :


// codé sous linux
// compilé avec gcc-4.1.2

Le principal défaut de cet algorythme, c'est que je n'ai pas encore chercher a verifier si chaque signature est unique, il faudrait que je fasse un programme qui vérifie cela.

Aussi, il y a une erreur de segmentation qui apparait de temps a autre, surement un probleme de pointeur ... si quelqu'un trouve pourquoi sa bug, sa serait pas mal :p

Voila, c'est pas tres utile, mais j'aime bien le concept :p

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Du même auteur (cs_Gwaihir)