*!* Objet : Implémention en VisualFoxPro de l'algorithme de hachage SHA1 *!* Auteur : C.Chenavier *!* Version : 1.00 - 15/11/2004 FUNCTION SHA1( cMessage ) PRIVATE HO, H1, H2, H3, H4 LOCAL nNbBlocs, nHigh, nLow H0 = 0x67452301 H1 = 0xEFCDAB89 H2 = 0x98BADCFE H3 = 0x10325476 H4 = 0xC3D2E1F0 M.nNbBlocs = LEN(M.cMessage) / 64 ** Si au départ, la taille du message n'est pas un multiple de 512, ** alors l'algorithme complète le message en ajoutant un 1 et ** autant de 0 que nécessaires et les 8 derniers octets servent ** à stocker la longueur du message. M.nLen = LEN(M.cMessage) M.nReste = MOD(M.nLen, 64) IF M.nReste > 0 OR M.nLen = 0 M.nNbBlocs = M.nNbBlocs + 1 IF M.nReste > 55 M.cMessage = M.cMessage + CHR(2^7) + REPLICATE(CHR(0), (64 - M.nReste) + 55) M.nNbBlocs = M.nNbBlocs + 1 ELSE M.cMessage = M.cMessage + CHR(2^7) + REPLICATE(CHR(0), (55 - M.nReste)) ENDIF M.nHigh = (M.nLen*8) / 2^32 M.nLow = MOD(M.nLen*8, 2^32) M.cMessage = M.cMessage + CHR(BITAND(BITRSHIFT(M.nHigh, 24), 0xFF)) ; && 56 + CHR(BITAND(BITRSHIFT(M.nHigh, 16), 0xFF)) ; && 57 + CHR(BITAND(BITRSHIFT(M.nHigh, 8), 0xFF)) ; && 58 + CHR(BITAND(M.nHigh, 0xFF)) ; && 59 + CHR(BITAND(BITRSHIFT(M.nLow, 24), 0xFF)) ; && 60 + CHR(BITAND(BITRSHIFT(M.nLow, 16), 0xFF)) ; && 61 + CHR(BITAND(BITRSHIFT(M.nLow, 8), 0xFF)) ; && 62 + CHR(BITAND(M.nLow, 0xFF)) && 63 ENDIF * NB! lisasin local i LOCAL i FOR I = 1 TO M.nNbBlocs DO SHA1_ProcessBloc WITH SUBSTR(M.cMessage, 1 + 64*(I-1), 64) ENDFOR RETURN SUBSTR(TRANSFORM(H0,"@0"),3) + ; SUBSTR(TRANSFORM(H1,"@0"),3) + ; SUBSTR(TRANSFORM(H2,"@0"),3) + ; SUBSTR(TRANSFORM(H3,"@0"),3) + ; SUBSTR(TRANSFORM(H4,"@0"),3) PROCEDURE SHA1_ProcessBloc LPARAMETERS cBloc LOCAL I, A, B, C, D, E, nTemp LOCAL ARRAY W(80) ** Pour chaque bloc de 512 bits, on divise le bloc en 16 mots de 32 bits ** et on les affecte respectivement à W1, W2...W16. FOR I = 1 TO 16 W(I) = BITLSHIFT(ASC(SUBSTR(M.cBloc, (I-1) * 4 + 1, 1)), 24) + ; BITLSHIFT(ASC(SUBSTR(M.cBloc, (I-1) * 4 + 2, 1)), 16) + ; BITLSHIFT(ASC(SUBSTR(M.cBloc, (I-1) * 4 + 3, 1)), 8) + ; ASC(SUBSTR(M.cBloc, (I-1) * 4 + 4, 1)) ENDFOR ** Pour I variant de 17 à 80, on affecte les mots Wi de la manière suivante : ** Wi = Wi-3 XOR Wi-8 XOR Wi-14 XOR Wi-16 FOR I = 17 TO 80 W(i) = BitLRotate(1, BITXOR(W(i-3), W(i-8), W(i-14), W(i-16))) ENDFOR A = H0 B = H1 C = H2 D = H3 E = H4 ** Pour I variant de 1 à 80 et avec Sn un décalage circulaire gauche de n bits, ** on effectue les calculs suivants : FOR I = 1 TO 20 M.nTemp = BitLRotate(5,A) + BITOR(BITAND(B,C), BITAND(BITNOT(B), D)) + ; E + W(i) + 0x5A827999 E = D D = C C = BitLRotate(30,B) B = A A = M.nTemp ENDFOR FOR I = 21 TO 40 M.nTemp = BitLRotate(5,A) + BITXOR(B, C, D) + E + W(i) + 0x6ED9EBA1 E = D D = C C = BitLRotate(30,B) B = A A = M.nTemp ENDFOR FOR I = 41 TO 60 M.nTemp = BitLRotate(5,A) + BITOR(BITAND(B,C), BITAND(B,D), BITAND(C,D)) + ; E + W(i) + 0x8F1BBCDC E = D D = C C = BitLRotate(30,B) B = A A = M.nTemp ENDFOR FOR I = 61 TO 80 M.nTemp = BitLRotate(5,A) + BITXOR(B, C, D) + E + W(i) + 0xCA62C1D6 E = D D = C C = BitLRotate(30,B) B = A A = M.nTemp ENDFOR H0 = H0 + A H1 = H1 + B H2 = H2 + C H3 = H3 + D H4 = H4 + E RETURN FUNCTION BitLRotate( nBits, nWord ) RETURN BITLSHIFT(M.nWord, M.nBits) + BITRSHIFT(M.nWord, (32-(M.nBits)))