读书人

请问:SHA1算法有没有纯VFP代码

发布时间: 2012-02-20 21:18:23 作者: rapoo

请教:SHA1算法有没有纯VFP代码?
据说SHA1碰撞的机率很小,想在程序中试试。
DLL或FLL就不想要了,只想要纯VFP代码实现。


[解决办法]
SHA1 加密

*!* 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

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

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)

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

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

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)))

[解决办法]
SHA1 解码

* Function: sha1encoder
* Description: Perform an SHA1 encoding on a text parameter

FUNCTION sha1encoder(lcMessage)

PRIVATE HO, H1, H2, H3, H4
LOCAL lnNumberOfBlocks, lnHigh, lnLow

H0 = 0x67452301
H1 = 0xEFCDAB89
H2 = 0x98BADCFE
H3 = 0x10325476
H4 = 0xC3D2E1F0

* Concatenate to the message a "1" followed by as many zeros as necessary
* to make the length a multiple of 512 with the last 8 bytes storing the length
* of the message.

lnLength = LEN(lcMessage)

* append bits 10000000
lcMessage = lcMessage + CHR(2^7)

* add as many 0 bytes as required to have message bit length a multiple of 512
* with the last 8 bytes being the number of bits in the original message.
lnRemainder = MOD(LEN(lcMessage), 64)
IF lnRemainder > 56
lcMessage = lcMessage + REPLICATE(CHR(0), (64 - lnRemainder) + 56)
ELSE
lcMessage = lcMessage + REPLICATE(CHR(0), (56 - lnRemainder))
ENDIF
lnHigh = (lnLength*8) / 2^32
lnLow = MOD(lnLength*8, 2^32)
lcMessage = lcMessage + CHR(BITAND(BITRSHIFT(lnHigh, 24), 0xFF)) ; && 56
+ CHR(BITAND(BITRSHIFT(lnHigh, 16), 0xFF)) ; && 57
+ CHR(BITAND(BITRSHIFT(lnHigh, 8), 0xFF)) ; && 58
+ CHR(BITAND(lnHigh, 0xFF)) ; && 59
+ CHR(BITAND(BITRSHIFT(lnLow, 24), 0xFF)) ; && 60
+ CHR(BITAND(BITRSHIFT(lnLow, 16), 0xFF)) ; && 61
+ CHR(BITAND(BITRSHIFT(lnLow, 8), 0xFF)) ; && 62
+ CHR(BITAND(lnLow, 0xFF)) && 63

lnNumberOfBlocks = LEN(lcMessage) / 64

LOCAL I
FOR I = 1 TO lnNumberOfBlocks
DO SHA1_ProcessBlock WITH SUBSTR(lcMessage, 1 + 64*(I-1), 64)
ENDFOR

lcDigest = 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)

* return the 20 character string for the 40 hex digit message digest.

lcReturnValue = ""
FOR i = 1 TO 20
lnValue = HexCharToDec(lcDigest, i * 2 - 1) * 16 + HexCharToDec(lcDigest, i * 2)
lcReturnValue = lcReturnValue + CHR(lnValue)
ENDFOR

RETURN lcReturnValue

PROCEDURE SHA1_ProcessBlock

LPARAMETERS cBlock

LOCAL I, A, B, C, D, E, nTemp
LOCAL ARRAY W(80)

* For each block of 512 bits, divide the block into 16 words of 32 bits and
* assign them to W1, W2... W16.

FOR I = 1 TO 16
W(I) = Word32Bits(BITLSHIFT(ASC(SUBSTR(cBlock, (I - 1) * 4 + 1, 1)), 24) ;
+ BITLSHIFT(ASC(SUBSTR(cBlock, (I - 1) * 4 + 2, 1)), 16) ;
+ BITLSHIFT(ASC(SUBSTR(cBlock, (I - 1) * 4 + 3, 1)), 8) ;


+ ASC(SUBSTR(cBlock, (I - 1) * 4 + 4, 1)))
ENDFOR

* For I varying from 17 to 80, one affects the W(I) words in the following way:
* W(I) = W(I-3) XOR W(I-8) XOR W(I-14) XOR W(I-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

*For I varying from 1 to 80 and with Sn a left circular shift of N bits,
* one carries out following calculations:

FOR I = 1 TO 80
nTemp = BitLRotate(5, A) + E + W(I)
DO CASE
CASE I <= 20
nTemp = nTemp + BITOR(BITAND(B, C), BITAND(BITNOT(B), D)) + 0x5A827999
CASE BETWEEN(I, 21, 40)
nTemp = nTemp + BITXOR(B, C, D) + 0x6ED9EBA1
CASE BETWEEN(I, 41, 60)
nTemp = nTemp + BITOR(BITAND(B, C), BITAND(B, D), BITAND(C, D)) + 0x8F1BBCDC
CASE I >= 61
nTemp = nTemp + BITXOR(B, C, D) + 0xCA62C1D6
ENDCASE
nTemp = Word32Bits(nTemp)

E = D
D = C
C = BitLRotate(30, B)
B = A
A = nTemp
ENDFOR

H0 = Word32Bits(H0 + A)
H1 = Word32Bits(H1 + B)
H2 = Word32Bits(H2 + C)
H3 = Word32Bits(H3 + D)
H4 = Word32Bits(H4 + E)
RETURN

FUNCTION BitLRotate(nBits, nWord)
RETURN Word32Bits(BITOR(BITLSHIFT(nWord, nBits), BITRSHIFT(nWord, (32 - nBits))))
ENDFUNC

FUNCTION Word32Bits(lnValue)
LOCAL ln32Bits
ln32Bits = BITAND(lnValue, 2^32 - 1)
DO WHILE ln32Bits < 0
ln32Bits = ln32Bits + 2^32
ENDDO
RETURN ln32Bits
ENDFUNC

FUNCTION HexCharToDec(lcString, lnPosition)
lcChar = SUBSTR(lcString,lnPosition,1)
IF BETWEEN(lcChar, '0', '9')
RETURN VAL(lcChar)
ELSE && BETWEEN(lcChar, 'A', 'F')
RETURN ASC(lcChar) - ASC('A') + 10
ENDIF
ENDFUNC

读书人网 >VFP

热点推荐