Note that the original code doesn't just concatenate the string version of integer nChar onto sCryptedPwd - it converts the integer to a single character with an ascii code corresponding to the integer and then concatenates that character onto the string
(and C# has no problem concatenating a character onto a string).
Can anyone read C .................. or better yet, convert to C#?
void crypt_passwd_prcd( Crypting, userid, passwd, new_passwd )
long Crypting;
char userid[9];
char passwd[9];
char new_passwd[9];
{
int i, j, c, l, e;
char key[80];
strcpy(new_passwd, passwd);
strcpy(key, userid);
l = strlen(key);
for (i=0; i<l; i++)
{
if (isupper(key[i]) || islower(key[i]))
{
if (isupper(key[i]))
key[i] = (char)tolower(key[i]);
key[i] -= 'a';
}
else
{
for (j=i; j<l; j++)
{
key[j] = key[j+1];
}
l = l - 1;
if ( l == 0 )
{
key[0] = 'b';
key[1] = 'a';
key[2] = 'd';
l = 3;
}
i--;
}
}
i = 0;
j = 0;
while (new_passwd[j] != '\0') {
c = new_passwd[j];
if (isupper(c) || islower(c))
{
if (isupper(c))
e = c - 'A';
else
e = c - 'a';
if (Crypting)
e = (e + key[i]) % 26;
else
{
e = (e - key[i]) % 26;
if (e < 0)
e += 26;
}
if (isupper(c))
e += 'A';
else
e += 'a';
new_passwd[j] = (char)e;
}
i++;
if (i == l)
i = 0;
j++;
}
}
I made a few minor changes such that a new password is returned (instead of being a void operation) :
public string CryptPassword(bool crypting, string userid,string passwd)
{
//Your loop variables
int i,j,l,e;
char c;
//StringBuilder objects to more easily handle string manipulation
StringBuilder key = new StringBuilder(userid);
StringBuilder newPassword = new StringBuilder(passwd);
l = key.Length;
//Iterate through the key
for(i=0; i<l;i++)
{
if(char.IsUpper(key[i]) || char.IsLower(key[i]))
{
if(char.IsUpper(key[i]))
{
key[i] = char.ToLower(key[i]);
key[i] -= 'a';
}
else
{
for (j=i; j<l; j++)
{
key[j] = key[j+1];
}
l = l - 1;
if ( l == 0 )
{
key[0] = 'b';
key[1] = 'a';
key[2] = 'd';
l = 3;
}
i--;
}
}
}
i = 0;
j = 0;
while (newPassword[j] != '\0')
{
c = newPassword[j];
if (char.IsUpper(c) || char.IsLower(c))
{
if (char.IsUpper(c))
e = c - 'A';
else
e = c - 'a';
if(crypting)
e = (e + key[i]) % 26;
else
{
e = (e - key[i]) % 26;
if (e < 0)
e += 26;
}
if (char.IsUpper(c))
e += 'A';
else
e += 'a';
newPassword[j] = (char)e;
}
i++;
if (i == l)
i = 0;
j++;
}
//Returns your new password
return newPassword.ToString();
}
By no means is this an optimized form, I just threw together a conversion that should basically work.
You can't change a character in a string directly, so the following uses a helper method which we use in our C++ to C# converter:
private void crypt_passwd_prcd(ref int Crypting string userid[9] sbyte passwd[9] sbyte new_passwd)
{
int i;
int j;
int c;
int l;
int e;
string key = new string(new char[80]);
new_passwd = passwd;
key = userid;
l = key.Length;
for (i = 0; i < l; i++)
{
if (char.IsUpper(key[i]) || char.IsLower(key[i]))
{
if (char.IsUpper(key[i]))
key = StringFunctions.ChangeCharacter(key, i, (sbyte)char.ToLower(key[i]));
key[i] -= 'a';
}
else
{
for (j = i; j < l; j++)
{
key = StringFunctions.ChangeCharacter(key, j, key[j + 1]);
}
l = l - 1;
if (l == 0)
{
key = StringFunctions.ChangeCharacter(key, 0, 'b');
key = StringFunctions.ChangeCharacter(key, 1, 'a');
key = StringFunctions.ChangeCharacter(key, 2, 'd');
l = 3;
}
i--;
}
}
i = 0;
j = 0;
while (new_passwd[j] != '\0')
{
c = new_passwd[j];
if (char.IsUpper(c) || char.IsLower(c))
{
if (char.IsUpper(c))
e = c - 'A';
else
e = c - 'a';
if (Crypting)
e = (e + key[i]) % 26;
else
{
e = (e - key[i]) % 26;
if (e < 0)
e += 26;
}
if (char.IsUpper(c))
e += 'A';
else
e += 'a';
new_passwd = StringFunctions.ChangeCharacter(new_passwd, j, (sbyte)e);
}
i++;
if (i == l)
i = 0;
j++;
}
}
internal static class StringFunctions
{
//------------------------------------------------------------------------------------
// This method allows replacing a single character in a string, to help convert
// C++ code where a single character in a character array is replaced.
//------------------------------------------------------------------------------------
internal static string ChangeCharacter(string sourcestring, int charindex, char changechar)
{
return (charindex > 0 ? sourcestring.Substring(0, charindex) : "")
+ changechar.ToString() + (charindex < sourcestring.Length - 1 ? sourcestring.Substring(charindex + 1) : "");
}
}
Firstly, this is some of the worst C code that I've ever seen. Clearly the original programmer had never heard of pointers.
Secondly, this is some of the worst cryptography I've ever seen. You should really be flagging this as being a risk. and recommending that it be changed at your earliest convenience. As an aside, a general rule of cryptography is that if you invent your
own, it's probably rubbish. This code confirms that rule.
Back to the code, here is my read of what it is actually attempting to do.
The first for loop attempts to convert the key into an array of zero-based characters (note, not the character '0', but a character with the value of 0). As part of its processing, it also skips any non-character input.
Thus "AaA" would become 000, and "ZzZ" would become 252525 (three characters, of value 25). Similarly "A1B2C3" would become a key of just three characters with the values 0, 1 and 2 respectively.
In the event that the user id contains no A-Z characters, the key that is generated is the three characters with the values of 1,0 and 3 (which represent "bad".
It then "encrypts" or "decrypts" the password by adding (or subtracting) the value of a key character to each of the characters in the password. It uses each character from the generated key in turn. A quick example shows how this works
Given
User ID: abc
Password: DEF
then the new password is
D (which equals 'D' + ('a' - 'a'))
F ( 'E' + ('b' - 'a')
H ('F' + ('c' - 'a')
Similarly, given
User Id: c1b
Password: XyZ
Then the generated key becomes the characters with the value of 2 and 0, and the output becomes
Z 'A' + ( 23 + ('c' + 'a'))
z 'a' + (24 + ('b' + 'a')) (Note that the 1 in the user id has been ignored)
B 'A' + ((25 + ('c' + 'a')) Modulus 26) (Note that the modulus kicks in here, and we're looped the key to use the 'c')
The following class contains a method to reproduce this, with one caveat. The original code assumed user ids and passwords of up to eight characters (plus a terminating null). This method will work with strings of any length.
public static class Cryptor
{
public static string CryptDecrypt(bool isEncrypting, string userId, string password)
{
string key = GetKeyFromUserId(userId);
StringBuilder sb = new StringBuilder();
int temp;
int keyIndex = 0;
foreach (var c in password)
{
if (!Char.IsLetter(c))
throw new ArgumentException("Password must only contain letters A - Z in upper or lower case");
temp = GetZeroBasedChar(c);
if (isEncrypting)
temp = (char) ((temp + key[keyIndex]) % 26);
else
{
temp = temp - key[keyIndex];
if (temp < 0)
temp = temp + 26;
}
sb.Append((char)(Char.IsUpper(c) ? temp + 'A' : temp + 'a'));
keyIndex = (keyIndex + 1) % key.Length;
}
return sb.ToString();
}
private static char GetZeroBasedChar( char c )
{
return (char) (char.IsUpper(c) ? c - 'A' : c - 'a');
}
private static string GetKeyFromUserId(string userId)
{
StringBuilder sb = new StringBuilder();
foreach (var c in userId)
{
if (Char.IsLetter(c))
{
sb.Append( GetZeroBasedChar(c) );
}
}
string key = sb.ToString();
if (string.IsNullOrEmpty(key))
{
return GetKeyFromUserId("bad");
}
return key;
}
}
Once again, I'd reiterate that this is very poor cryptography. But the code above should let you work with the existing passwords.
David Anton
Contributor
3704 Points
638 Posts
Re: Need help converting a very small piece of VB to C#
Feb 06, 2013 02:42 PM|LINK
You'll need:
Note that the original code doesn't just concatenate the string version of integer nChar onto sCryptedPwd - it converts the integer to a single character with an ascii code corresponding to the integer and then concatenates that character onto the string (and C# has no problem concatenating a character onto a string).
http://www.tangiblesoftwaresolutions.com
Instant C# - VB to C# Converter
Instant VB - C# to VB Converter
matt.gulick
Member
75 Points
84 Posts
Re: Need help converting a very small piece of VB to C#
Feb 07, 2013 05:11 PM|LINK
This did produce output, but it was still incorrect. I'm gonna see if I can get my hands on the original C code.
matt.gulick
Member
75 Points
84 Posts
Re: Need help converting a very small piece of VB to C#
Feb 08, 2013 11:42 AM|LINK
Can anyone read C .................. or better yet, convert to C#?
void crypt_passwd_prcd( Crypting, userid, passwd, new_passwd ) long Crypting; char userid[9]; char passwd[9]; char new_passwd[9]; { int i, j, c, l, e; char key[80]; strcpy(new_passwd, passwd); strcpy(key, userid); l = strlen(key); for (i=0; i<l; i++) { if (isupper(key[i]) || islower(key[i])) { if (isupper(key[i])) key[i] = (char)tolower(key[i]); key[i] -= 'a'; } else { for (j=i; j<l; j++) { key[j] = key[j+1]; } l = l - 1; if ( l == 0 ) { key[0] = 'b'; key[1] = 'a'; key[2] = 'd'; l = 3; } i--; } } i = 0; j = 0; while (new_passwd[j] != '\0') { c = new_passwd[j]; if (isupper(c) || islower(c)) { if (isupper(c)) e = c - 'A'; else e = c - 'a'; if (Crypting) e = (e + key[i]) % 26; else { e = (e - key[i]) % 26; if (e < 0) e += 26; } if (isupper(c)) e += 'A'; else e += 'a'; new_passwd[j] = (char)e; } i++; if (i == l) i = 0; j++; } }Rion William...
All-Star
27414 Points
4542 Posts
Re: Need help converting a very small piece of VB to C#
Feb 08, 2013 12:24 PM|LINK
I made a few minor changes such that a new password is returned (instead of being a void operation) :
public string CryptPassword(bool crypting, string userid,string passwd) { //Your loop variables int i,j,l,e; char c; //StringBuilder objects to more easily handle string manipulation StringBuilder key = new StringBuilder(userid); StringBuilder newPassword = new StringBuilder(passwd); l = key.Length; //Iterate through the key for(i=0; i<l;i++) { if(char.IsUpper(key[i]) || char.IsLower(key[i])) { if(char.IsUpper(key[i])) { key[i] = char.ToLower(key[i]); key[i] -= 'a'; } else { for (j=i; j<l; j++) { key[j] = key[j+1]; } l = l - 1; if ( l == 0 ) { key[0] = 'b'; key[1] = 'a'; key[2] = 'd'; l = 3; } i--; } } } i = 0; j = 0; while (newPassword[j] != '\0') { c = newPassword[j]; if (char.IsUpper(c) || char.IsLower(c)) { if (char.IsUpper(c)) e = c - 'A'; else e = c - 'a'; if(crypting) e = (e + key[i]) % 26; else { e = (e - key[i]) % 26; if (e < 0) e += 26; } if (char.IsUpper(c)) e += 'A'; else e += 'a'; newPassword[j] = (char)e; } i++; if (i == l) i = 0; j++; } //Returns your new password return newPassword.ToString(); }By no means is this an optimized form, I just threw together a conversion that should basically work.
David Anton
Contributor
3704 Points
638 Posts
Re: Need help converting a very small piece of VB to C#
Feb 08, 2013 03:37 PM|LINK
You can't change a character in a string directly, so the following uses a helper method which we use in our C++ to C# converter:
private void crypt_passwd_prcd(ref int Crypting string userid[9] sbyte passwd[9] sbyte new_passwd) { int i; int j; int c; int l; int e; string key = new string(new char[80]); new_passwd = passwd; key = userid; l = key.Length; for (i = 0; i < l; i++) { if (char.IsUpper(key[i]) || char.IsLower(key[i])) { if (char.IsUpper(key[i])) key = StringFunctions.ChangeCharacter(key, i, (sbyte)char.ToLower(key[i])); key[i] -= 'a'; } else { for (j = i; j < l; j++) { key = StringFunctions.ChangeCharacter(key, j, key[j + 1]); } l = l - 1; if (l == 0) { key = StringFunctions.ChangeCharacter(key, 0, 'b'); key = StringFunctions.ChangeCharacter(key, 1, 'a'); key = StringFunctions.ChangeCharacter(key, 2, 'd'); l = 3; } i--; } } i = 0; j = 0; while (new_passwd[j] != '\0') { c = new_passwd[j]; if (char.IsUpper(c) || char.IsLower(c)) { if (char.IsUpper(c)) e = c - 'A'; else e = c - 'a'; if (Crypting) e = (e + key[i]) % 26; else { e = (e - key[i]) % 26; if (e < 0) e += 26; } if (char.IsUpper(c)) e += 'A'; else e += 'a'; new_passwd = StringFunctions.ChangeCharacter(new_passwd, j, (sbyte)e); } i++; if (i == l) i = 0; j++; } } internal static class StringFunctions { //------------------------------------------------------------------------------------ // This method allows replacing a single character in a string, to help convert // C++ code where a single character in a character array is replaced. //------------------------------------------------------------------------------------ internal static string ChangeCharacter(string sourcestring, int charindex, char changechar) { return (charindex > 0 ? sourcestring.Substring(0, charindex) : "") + changechar.ToString() + (charindex < sourcestring.Length - 1 ? sourcestring.Substring(charindex + 1) : ""); } }http://www.tangiblesoftwaresolutions.com
Instant C# - VB to C# Converter
Instant VB - C# to VB Converter
matt.gulick
Member
75 Points
84 Posts
Re: Need help converting a very small piece of VB to C#
Feb 11, 2013 05:00 PM|LINK
Thank-you for your reply David, but your code contains syntax errors to numerous to mention.
David Anton
Contributor
3704 Points
638 Posts
Re: Need help converting a very small piece of VB to C#
Feb 12, 2013 05:44 AM|LINK
Sorry - the parameter list got messed up in the conversion - replace the method header with:
There will be other adjustments to make, but this gets rid of most of the problems I think.
http://www.tangiblesoftwaresolutions.com
Instant C# - VB to C# Converter
Instant VB - C# to VB Converter
DMW
All-Star
15943 Points
2353 Posts
Re: Need help converting a very small piece of VB to C#
Feb 12, 2013 08:15 AM|LINK
Matt
Firstly, this is some of the worst C code that I've ever seen. Clearly the original programmer had never heard of pointers.
Secondly, this is some of the worst cryptography I've ever seen. You should really be flagging this as being a risk. and recommending that it be changed at your earliest convenience. As an aside, a general rule of cryptography is that if you invent your own, it's probably rubbish. This code confirms that rule.
Back to the code, here is my read of what it is actually attempting to do.
The first for loop attempts to convert the key into an array of zero-based characters (note, not the character '0', but a character with the value of 0). As part of its processing, it also skips any non-character input.
Thus "AaA" would become 000, and "ZzZ" would become 252525 (three characters, of value 25). Similarly "A1B2C3" would become a key of just three characters with the values 0, 1 and 2 respectively.
In the event that the user id contains no A-Z characters, the key that is generated is the three characters with the values of 1,0 and 3 (which represent "bad".
It then "encrypts" or "decrypts" the password by adding (or subtracting) the value of a key character to each of the characters in the password. It uses each character from the generated key in turn. A quick example shows how this works
Given
User ID: abc
Password: DEF
then the new password is
D (which equals 'D' + ('a' - 'a'))
F ( 'E' + ('b' - 'a')
H ('F' + ('c' - 'a')
Similarly, given
User Id: c1b
Password: XyZ
Then the generated key becomes the characters with the value of 2 and 0, and the output becomes
Z 'A' + ( 23 + ('c' + 'a'))
z 'a' + (24 + ('b' + 'a')) (Note that the 1 in the user id has been ignored)
B 'A' + ((25 + ('c' + 'a')) Modulus 26) (Note that the modulus kicks in here, and we're looped the key to use the 'c')
The following class contains a method to reproduce this, with one caveat. The original code assumed user ids and passwords of up to eight characters (plus a terminating null). This method will work with strings of any length.
public static class Cryptor { public static string CryptDecrypt(bool isEncrypting, string userId, string password) { string key = GetKeyFromUserId(userId); StringBuilder sb = new StringBuilder(); int temp; int keyIndex = 0; foreach (var c in password) { if (!Char.IsLetter(c)) throw new ArgumentException("Password must only contain letters A - Z in upper or lower case"); temp = GetZeroBasedChar(c); if (isEncrypting) temp = (char) ((temp + key[keyIndex]) % 26); else { temp = temp - key[keyIndex]; if (temp < 0) temp = temp + 26; } sb.Append((char)(Char.IsUpper(c) ? temp + 'A' : temp + 'a')); keyIndex = (keyIndex + 1) % key.Length; } return sb.ToString(); } private static char GetZeroBasedChar( char c ) { return (char) (char.IsUpper(c) ? c - 'A' : c - 'a'); } private static string GetKeyFromUserId(string userId) { StringBuilder sb = new StringBuilder(); foreach (var c in userId) { if (Char.IsLetter(c)) { sb.Append( GetZeroBasedChar(c) ); } } string key = sb.ToString(); if (string.IsNullOrEmpty(key)) { return GetKeyFromUserId("bad"); } return key; } }Once again, I'd reiterate that this is very poor cryptography. But the code above should let you work with the existing passwords.
Dave
matt.gulick
Member
75 Points
84 Posts
Re: Need help converting a very small piece of VB to C#
Feb 12, 2013 11:35 AM|LINK
Thanks David, but that was the only part I could figure out myself.
matt.gulick
Member
75 Points
84 Posts
Re: Need help converting a very small piece of VB to C#
Feb 12, 2013 12:36 PM|LINK
Thank-you so much for your help. I couldn't agree more, but at this time I can only make a web-based gui that works with the existing forms app.
I made the following changes to your code to allow for numbers in the password.
public static string CryptDecrypt(bool isEncrypting, string userId, string password) { string key = GetKeyFromUserId(userId); StringBuilder sb = new StringBuilder(); int temp; int keyIndex = 0; foreach (var c in password) { //if ((!Char.IsLetter(c)) || (!Char.IsNumber(c))) // throw new ArgumentException("Password must only contain letters A - Z in upper or lower case"); if (Char.IsNumber(c)) { temp = Convert.ToInt32(c) - 48; sb.Append(temp); } else { temp = GetZeroBasedChar(c); if (isEncrypting) temp = (char)((temp + key[keyIndex]) % 26); else { temp = temp - key[keyIndex]; if (temp < 0) temp = temp + 26; } sb.Append((char)(Char.IsUpper(c) ? temp + 'A' : temp + 'a')); } keyIndex = (keyIndex + 1) % key.Length; } return sb.ToString(); }It did output the correct decryption on my test id.
After a jump for joy I then tried another id
Do these results make sense to you, cause they don't to me? If one succeeded, then I don't see why the other failed.
Thank-you again for your assistance.