Re: MySQL encode/decode
This is as close to a line by line translation of the MySQL Source as I could come for encode/decode. I will be working with this and cleaning it up a little. C# and C++ have some minor differences in data-types and unicode/ascii encoding. Once I got past these (as well as refresh my C++) it was almost totally a line by line process.
Note: C# also does not safely support pointer manipulation so I removed all.
Just provide the password in the constructor and pass a string to the encode or decode function.
using System;
using System.Collections.Generic;
using System.Text;
namespace MySQLEncode
{
/// <summary>
/// Provides offline MySQL encode/decode
/// </summary>
class SQLCrypt
{
////////////////////
/// Private Members
////////////////////
#region Private Members
private struct rand_struct
{
public uint seed1;
public uint seed2;
public uint max_value;
public double max_value_dbl;
}
private char[] decode_buff = new char[256];
private char[] encode_buff = new char[256];
private rand_struct rand;
private rand_struct org_rand;
private ushort shift;
#endregion
////////////////////
/// Constructor
////////////////////
#region Constructor
public SQLCrypt(string password)
{
///////////
// Data
///////////
#region Data
uint[] rand_nr;
#endregion
///////////
// Code
///////////
#region Code
hash_password(out rand_nr, password);
crypt_init(rand_nr);
#endregion
}
#endregion
////////////////////
/// Public Methods
////////////////////
#region Public Methods
public string encode(string str)
{
///////////
// Data
///////////
#region Data
char[] c_Str;
byte[] b_Str;
byte[] b_encode;
Encoding ascii;
#endregion
///////////
// Code
///////////
#region Code
ascii = Encoding.Default;
c_Str = new char[str.Length];
c_Str = str.ToCharArray();
b_Str = ascii.GetBytes(c_Str);
b_encode = ascii.GetBytes(encode_buff);
for (ushort i = 0; i < str.Length; i++)
{
shift ^= (ushort)(my_rnd(ref rand) * 255.0);
ushort idx = (ushort)b_Str;
b_Str = (byte)(b_encode[idx] ^ shift);
shift ^= idx;
}
c_Str = ascii.GetChars(b_Str);
return new string(c_Str);
#endregion
}
public string decode(string str)
{
///////////
// Data
///////////
#region Data
char[] c_Str;
byte[] b_Str;
byte[] b_decode;
Encoding ascii;
#endregion
///////////
// Code
///////////
#region Code
ascii = Encoding.Default;
c_Str = new char[str.Length];
c_Str = str.ToCharArray();
b_Str = ascii.GetBytes(c_Str);
b_decode = ascii.GetBytes(decode_buff);
for (ushort i = 0; i < str.Length; i++)
{
shift ^= (ushort)(my_rnd(ref rand) * 255.0);
ushort idx = (ushort)(b_Str ^ shift);
b_Str = b_decode[idx];
shift ^= (ushort)b_Str;
}
c_Str = ascii.GetChars(b_Str);
return new string(c_Str);
#endregion
}
#endregion
////////////////////
/// Private Methods
////////////////////
#region Private Methods
private void crypt_init(uint[] rand_nr)
{
///////////
// Data
///////////
#region Data
ushort i;
byte[] b_decodebuff;
byte[] b_encodebuff;
Encoding ascii;
#endregion
///////////
// Code
///////////
#region Code
ascii = Encoding.Default;
randominit(out rand, rand_nr[0], rand_nr[1]);
b_decodebuff = new byte[256];
for (i = 0; i <= 255; i++)
{
b_decodebuff = (byte)i;
}
decode_buff = ascii.GetChars(b_decodebuff);
for (i = 0; i <= 255; i++)
{
ushort idx = (ushort)(my_rnd(ref rand) * 255.0);
char a = decode_buff[idx];
decode_buff[idx] = decode_buff;
decode_buff[+i] = a;
}
b_decodebuff = ascii.GetBytes(decode_buff);
b_encodebuff = new byte[256];
for (i = 0; i <= 255; i++)
{
b_encodebuff[b_decodebuff] = (byte)i;
}
encode_buff = ascii.GetChars(b_encodebuff);
org_rand = rand;
shift = 0;
#endregion
}
private double my_rnd(ref rand_struct rand_st)
{
///////////
// Data
///////////
#region Data
#endregion
///////////
// Code
///////////
#region Code
rand_st.seed1 = (rand_st.seed1 * 3 + rand_st.seed2) % rand_st.max_value;
rand_st.seed2 = (rand_st.seed1 + rand_st.seed2 + 33) % rand_st.max_value;
return (((double)rand_st.seed1) / rand_st.max_value_dbl);
#endregion
}
private void hash_password(out uint[] result, string password)
{
///////////
// Data
///////////
#region Data
uint nr = 1345345333;
uint add = 7;
uint nr2 = 0x12345671;
uint tmp;
#endregion
///////////
// Code
///////////
#region Code
result = new uint[2];
for (int i = 0; i < password.Length; i++)
{
if (password == ' ' || password == '\t')
continue;
tmp = (uint)password;
nr ^= (((nr & 63) + add) * tmp) + (nr << 8);
nr2 += (nr2 << 8) ^ nr;
add += tmp;
}
result[0] = (uint)nr & (((uint)1 << 31) - 1);
result[1] = (uint)nr2 & (((uint)1 << 31) - 1);
#endregion
}
private void randominit(out rand_struct rand_st, uint seed1, uint seed2)
{
///////////
// Data
///////////
#region Data
#endregion
///////////
// Code
///////////
#region Code
rand_st.max_value = 0x3FFFFFFF;
rand_st.max_value_dbl = (double)rand_st.max_value;
rand_st.seed1 = seed1 % rand_st.max_value;
rand_st.seed2 = seed2 % rand_st.max_value;
#endregion
}
#endregion
}
}
Subject
Written By
Posted
November 03, 2006 10:03AM
Re: MySQL encode/decode
November 03, 2006 12:30PM
November 06, 2006 09:55AM
Sorry, you can't reply to this topic. It has been closed.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion
of Oracle or any other party.