VFP implementation of the Cipher encryption

This is a VFP implementation of the Cipher encryption. Cipher50 C source code and the binary is available as separate downloads File #21474 and File #9222 at http://www.levelextreme.com.

Cipher was originally put into the public domain by Tom Rettig Associates in 1991 and has been re-produced by different parties as necessary for newer versions of FoxPro. Obviously, the VFP implementation is much slower than the C library and should be used for short strings, like passwords, only. The code has been tested under VFP 8.0 and VFP 9.0 but should work in previous versions. If it doesn't, feel free to modify it.

This is sample code. Add error handling and adjust to your requirements as necessary.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

*
* Parameters:
*   tcStr      - string to encrypt/decrypt
*   tcPassword - password to use for encryption/decryption 
*
*----------encrypt.prg----------
*
* Alias for cipher
FUNCTION encrypt
LPARAMETERS tcStr, tcPassword
RETURN cipher(tcStr, tcPassword)
*
*----------decrypt.prg----------
*
* Alias for cipher
FUNCTION decrypt
LPARAMETERS tcStr, tcPassword
RETURN cipher(tcStr, tcPassword)
*
*----------cipher.prg----------
FUNCTION cipher 
LPARAMETERS tcStr, tcPassword

#define   PW_MIN_LEN   3		&&  /* min  number of characters in the password */
#define   PW_MIN_NUM   1000		&&  /* min value for the password seed */

LOCAL lnStrLen, lnPassLen, lnPassNum, laPassword[1,2], lcPassword
LOCAL lcStrOut, lnPassPos, lnNum01, lcStrOut, lnInPos, lnPassPos

IF TYPE("tcStr") <> "C" ;
		OR TYPE("tcPassword") <> "C" ;
		OR LEN(tcPassword) < PW_MIN_LEN
	Error 11
ENDIF

lnStrLen = LEN(tcStr)

* Because of the bug in the original C code we've to add CHR(0) to the password and use it later
lcPassword = tcPassword + CHR(0)
lnPassLen = LEN(lcPassword)
DIMENSION laPassword[lnPassLen+1,2]
FOR lnPassPos=1 TO lnPassLen
	laPassword[lnPassPos,2] = SUBSTR(lcPassword,lnPassPos,1)
	laPassword[lnPassPos,1] = ASC(laPassword[lnPassPos,2])
ENDFOR

* Get seed value
lnPassNum = INT((((CipherGetPnum(lcPassword)/997) - 1) % 254) + 1 )
lcStrOut = ""
lnPassPos = 1

* Encode/decode each character
FOR lnInPos=0 TO lnStrLen-1
	* Get new seed value
	lnNum01 = (( lnPassNum + (lnInPos - lnStrLen)) - 1)
	lnPassNum = (ABS(lnNum01) % 254) * SIGN(lnNum01) + 1
	* Encode current character
	lnByte = BITXOR( ASC(SUBSTR(tcStr,lnInPos+1,1)), ;
		BITXOR(lnPassNum, laPassword[lnPassPos,1]))
	* Convert signed value to unsigned, if necessary
	lnByte = BITAND(lnByte, 0xFF)
	* If result is zero, use current character
	lcStrOut = lcStrOut + IIF(lnByte = 0, SUBSTR(tcStr,lnInPos+1,1), CHR(lnByte))
	* Advance to the next password character
	lnPassPos = IIF( lnPassPos => lnPassLen, 1, lnPassPos + 1)
ENDFOR

RETURN lcStrOut

* Returns a seed value based on the string passed as parameter
FUNCTION CipherGetPnum(tcStr)
LOCAL liRet, lnPos
liRet = 1
FOR lnPos=0 TO LEN(tcStr ) - 1
	liRet = liRet + ASC(SUBSTR(tcStr,lnPos+1,1)) + lnPos
ENDFOR
DO WHILE (liRet < PW_MIN_NUM)
	liRet = BITLSHIFT(liRet,1)
ENDDO
RETURN liRet

Comments

Thanks for share.

Thanks very much for sharing this code

Thanks a lot for this code you have given to us...hoped this will work with my program in VF9.. :)

Thanks for the Cipher50 VFP code. I have been looking for an encryption routine that is consistent with both Foxpro and .Net and this one works. Many VFP encryption routines use SYS() functions, etc that can't be reproduced in .Net but I was able to create a C# version of Cipher50 so I can read encrypted strings in both Foxpro and .Net

Could you please provide me a copy of the converted vfp program. I really need it. Thanks.

you can copy code from this page