Solved

Convert PHP function into C#

Posted on 2012-03-27
6
1,867 Views
Last Modified: 2012-04-01
I need help converting a, for me, complex php function into C# code.

PHP Function:
function ssha($password){
            mt_srand((double)microtime()*1000000);
            $salt = pack("CCCC", mt_rand(), mt_rand(), mt_rand(), mt_rand());
            $hash = base64_encode(pack("H*", sha1($password . $salt)) . $salt);
            $hash = str_replace('+', '@', $hash);
            $hash = str_replace('/', '.', $hash);
            return $hash;
}

Open in new window


My own C# code (that doesn't work):
public static string GetLegatoHash(string Password)
        {
            // mt_srand((double)microtime()*1000000);
            int seconds = DateTime.Now.Second;
            Random rnd = new Random(seconds);

            // $salt = pack("CCCC", mt_rand(), mt_rand(), mt_rand(), mt_rand());
            byte[] data = new byte[] { (byte)rnd.Next(), (byte)rnd.Next(), (byte)rnd.Next(), (byte)rnd.Next() };
            string salt = data[0].ToString() + data[1].ToString() + data[2].ToString() + data[3].ToString();
            
            // sha1($password . $salt)
            ASCIIEncoding UE = new ASCIIEncoding();
            byte[] HashValue, MessageBytes = UE.GetBytes((Password + salt));
            HashAlgorithm SHhash = new SHA1Managed();

            HashValue = SHhash.ComputeHash(data);

            // pack("H*", sha1($password . $salt))
            List<byte> hashdata = new List<byte>();
            foreach (byte b in HashValue)
            {
                byte nibbleLow = (byte)(b & 0x0F);
                byte nibbleHigh = (byte)((b & 0xF0) >> 4);

                hashdata.Add(nibbleHigh);
                hashdata.Add(nibbleLow);
            }

            foreach (byte b in data)
            {
                byte nibbleLow = (byte)(b & 0x0F);
                byte nibbleHigh = (byte)((b & 0xF0) >> 4);

                hashdata.Add(nibbleHigh);
                hashdata.Add(nibbleLow);
            }

            // base64_encode(pack("H*", sha1($password . $salt)) . $salt);
            byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(string.Join("", hashdata.ToArray()) + salt);
            string hash = System.Convert.ToBase64String(toEncodeAsBytes);

            //$hash = str_replace('+', '@', $hash);
            //$hash = str_replace('/', '.', $hash);
            hash.Replace("+", "@").Replace("/", ".");

            return hash;
        }

Open in new window

0
Comment
Question by:McLyd
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
6 Comments
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37771369
i am sure there is no tool to convert php to c#, however i have modified the code in c# as:-

public static string GetLegatoHash(string Password)
        {
            // mt_srand((double)microtime()*1000000);
            int seconds = DateTime.Now.Second;
            Random rnd = new Random(seconds);

            // $salt = pack("CCCC", mt_rand(), mt_rand(), mt_rand(), mt_rand());
            byte[] data = new byte[] { (byte)rnd.Next(), (byte)rnd.Next(), (byte)rnd.Next(), (byte)rnd.Next() };
            string salt = data[0].ToString() + data[1].ToString() + data[2].ToString() + data[3].ToString();

            // sha1($password . $salt)
            ASCIIEncoding UE = new ASCIIEncoding();
            byte[] HashValue, MessageBytes = UE.GetBytes((Password + salt));
            HashAlgorithm SHhash = new SHA1Managed();

            HashValue = SHhash.ComputeHash(data);

            // pack("H*", sha1($password . $salt))
            List<byte> hashdata = new List<byte>();
            foreach (byte b in HashValue)
            {
                byte nibbleLow = (byte)(b & 0x0F);
                byte nibbleHigh = (byte)((b & 0xF0) >> 4);

                hashdata.Add(nibbleHigh);
                hashdata.Add(nibbleLow);
            }

            foreach (byte b in data)
            {
                byte nibbleLow = (byte)(b & 0x0F);
                byte nibbleHigh = (byte)((b & 0xF0) >> 4);

                hashdata.Add(nibbleHigh);
                hashdata.Add(nibbleLow);
            }

            // base64_encode(pack("H*", sha1($password . $salt)) . $salt);
            
            byte[] toEncodeAsBytes = Encoding.ASCII.GetBytes(salt);
            hashdata.AddRange(toEncodeAsBytes);

            string hash = System.Convert.ToBase64String(hashdata.ToArray());

            //$hash = str_replace('+', '@', $hash);
            //$hash = str_replace('/', '.', $hash);
            hash.Replace("+", "@").Replace("/", ".");

            return hash;
        }

Open in new window


see if it works....
0
 

Author Comment

by:McLyd
ID: 37771400
Sorry, no go on that one. But probably a good modification though.

Any other ideas?
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37771452
any reasons for not using the code...
what challenge you see in it...
0
Why Off-Site Backups Are The Only Way To Go

You are probably backing up your data—but how and where? Ransomware is on the rise and there are variants that specifically target backups. Read on to discover why off-site is the way to go.

 

Author Comment

by:McLyd
ID: 37771498
Well, the problem is that it still isn't working. The C# code doesn't produce the same output as the php code does.

The challenge.... is that I don't know enough php to make the conversion on my own.
0
 

Accepted Solution

by:
McLyd earned 0 total points
ID: 37771709
Solved it!

Here is the working C# code:
        public static string GetLegatoHash(string Password)
        {
            // mt_srand((double)microtime()*1000000);
            int seconds = DateTime.Now.Second;
            Random rnd = new Random(seconds);

            // $salt = pack("CCCC", mt_rand(), mt_rand(), mt_rand(), mt_rand());
            byte[] data = new byte[] { (byte)rnd.Next(), (byte)rnd.Next(), (byte)rnd.Next(), (byte)rnd.Next() };
            string salt = data[0].ToString() + data[1].ToString() + data[2].ToString() + data[3].ToString();
            
            // sha1($password . $salt)
            ASCIIEncoding UE = new ASCIIEncoding();
            byte[] HashValue, MessageBytes = UE.GetBytes(Password + salt);
            HashAlgorithm SHhash = new SHA1Managed();
            HashValue = SHhash.ComputeHash(MessageBytes);

            // pack("H*", sha1($password . $salt))
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < HashValue.Length; i++)
            {
                sb.Append(HashValue[i].ToString("X2"));
            }
            byte[] PackHBytes = PackH(sb.ToString());

            // base64_encode(pack("H*", sha1($password . $salt)) . $salt);
            byte[] SaltBytes = Encoding.ASCII.GetBytes(salt);

            byte[] FinalBytes = new byte[PackHBytes.Length + SaltBytes.Length];
            System.Buffer.BlockCopy(PackHBytes, 0, FinalBytes, 0, PackHBytes.Length);
            System.Buffer.BlockCopy(SaltBytes, 0, FinalBytes, PackHBytes.Length, SaltBytes.Length);

            string hash = System.Convert.ToBase64String(FinalBytes);

            //$hash = str_replace('+', '@', $hash);
            //$hash = str_replace('/', '.', $hash);
            hash = hash.Replace("+", "@").Replace("/", ".");

            return hash;
        }

        private static byte[] PackH(string hex)
        {
            if ((hex.Length % 2) == 1) hex += '0';
            byte[] bytes = new byte[hex.Length / 2];
            for (int i = 0; i < hex.Length; i += 2)
            {
                bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
            }
            return bytes;
        }

Open in new window

0
 

Author Closing Comment

by:McLyd
ID: 37792761
It's the only solution that works.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Build an array called $myWeek which will hold the array elements Today, Yesterday and then builds up the rest of the week by the name of the day going back 1 week.   (CODE) (CODE) Then you just need to pass your date to the function. If i…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
The viewer will learn how to count occurrences of each item in an array.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

717 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question