using System; >using System.Linq; >using System.Text; > >namespace Cipher >{ > public class Cipher > { > private const int PwMinNum = 1000; > > public string Encrypt(string tcStr, string tcPassword) > { > byte[] tcStrBytes = Encoding.ASCII.GetBytes(tcStr); > int tcStrLength = tcStrBytes.Length; > > string lcPassword = tcPassword + '0'; > byte[] lcPasswordBytes = Encoding.ASCII.GetBytes(lcPassword); > int lnPassLen = lcPasswordBytes.Length - 1; > > int lnPassPos = 0; > > string lcStrOut = string.Empty; > > int lnPassNum = ((CipherGetPnum(lcPassword)/997 - 1)%254) + 1; > > for (int i = 0; i < tcStrLength;i++) > { > int lnNum01 = ((lnPassNum + (i - tcStrLength)) - 1); > lnPassNum = (Math.Abs(lnNum01)%254)*Math.Sign(lnNum01) + 1; > var lnByte = tcStrBytes[i] ^ (lnPassNum ^ lcPasswordBytes[lnPassPos]); > lnByte = lnByte & 0xFF; > lcStrOut = lcStrOut + (lnByte == 0 ? Convert.ToChar( tcStrBytes[i + 1]) : Convert.ToChar(lnByte)); > lnPassPos = lnPassPos>=lnPassLen ? 1:lnPassPos + 1; > } > return lcStrOut; > } > > private int CipherGetPnum(string tcStr) > { > byte[] ascii = Encoding.ASCII.GetBytes(tcStr); > int liRet = 1 + ascii.Select((t, i) => t + i).Sum(); > > while (liRet < PwMinNum) > { > liRet = liRet << 1; > } > return liRet; > } > } >}This is my C# code:
public class VfpCipher { public static string Cipher(string cString, string tcPassword) { string lcPassword; int lnPassLen; int lnPassPos; int iAsciiValue; int lnPassNum; int lnStrLen; lnStrLen = cString.Length; char ChrZero; ChrZero = (char)0; lcPassword = tcPassword + ChrZero.ToString(); // in VFP this was add CHR(0) to the Password string lnPassLen = lcPassword.Length; int[] laPassword = new int[lnPassLen+1]; for (lnPassPos = 0; lnPassPos < lnPassLen; lnPassPos++) { // Get one-character from the Password string and store the ASC()/ASCII value of it to the array. var charByte = System.Text.Encoding.GetEncoding(1252).GetBytes(lcPassword.Substring(lnPassPos, 1)); laPassword[lnPassPos] = Convert.ToInt32(charByte[0]); } // Get seed value lnPassNum = (int)((((CipherGetPnum(lcPassword) / 997) - 1) % 254) + 1); int lnByte; string lcStrOut = ""; lnPassPos = 0; // in VFP this is 1 but in C# the array is zero-based. int lnNum01; // Encode/decode each character for (int lnInPos=0; lnInPos < lnStrLen-1; lnInPos++) { // Get new seed value lnNum01 = (( lnPassNum + (lnInPos - lnStrLen)) - 1); lnPassNum = ( Math.Abs(lnNum01) % 254 ) * Math.Sign(lnNum01) + 1; // Get the character byte and extract the ASCII value of the character. var charByte = System.Text.Encoding.GetEncoding(1252).GetBytes(cString.Substring(lnInPos, 1)); iAsciiValue = Convert.ToInt32(charByte[0]); lnByte = (iAsciiValue ^ (lnPassNum ^ laPassword[lnPassPos])); // Convert signed value to unsigned, if necessary lnByte = lnByte & 0xFF; // If result is zero, use current character // Get one character string value of lnByte char cOneChar; cOneChar = (char)lnByte; string sOneChar; sOneChar = cOneChar.ToString(); lcStrOut = lcStrOut + (lnByte.Equals(0) ? cString.Substring(lnInPos, 1) : sOneChar); lnPassPos = (lnPassPos.CompareTo(lnPassLen-1) >= 0 ? 0 : lnPassPos + 1); } return lcStrOut; } public static int CipherGetPnum(string SeedString) { int liRet = 1; int iAsciiValue; for (int lnPos = 0; lnPos < SeedString.Length; lnPos++) { var charByte = System.Text.Encoding.GetEncoding(1252).GetBytes(SeedString.Substring(lnPos, 1)); iAsciiValue = Convert.ToInt32(charByte[0]); liRet = liRet + iAsciiValue + lnPos; } // Note that in Sergey's code the value 1000 is declared as constant. do { liRet = liRet << 1; } while (liRet < 1000); return liRet; } }