Re: MySQL encode/decode
Posted by: John Hamilton
Date: November 03, 2006 12:30PM

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        

    }
}


Options: ReplyQuote


Subject
Written By
Posted
October 30, 2006 06:56PM
October 31, 2006 11:33AM
October 31, 2006 12:44PM
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.