how to convert function from VB.net to C#?

329 views Asked by At

I have this function in VB.net and I am trying to convert this code from VB to C#.

Function HashEncode(strSecret)
' Function takes an ASCII string less than 2^61 characters long and 
' one way hash encrypts it using 160 bit encryption into a 40 digit hex value.
' The encoded hex value cannot be decoded to the original string value.
'
' This is the only function that you need to call for encryption.
'
' Written By: Mark G. Jager
' Written Date: 8/10/2000
'
' Free to distribute as long as code is not modified, and header is kept intact
'
' The author makes no warranties as to the validity, and/or authenticity of this code.
' You may use any code found herein at your own risk.
' This code was written to follow as closely as possible the standards found in
' Federal Information Processing Standards Publication (FIPS PUB 180-1)
' http://csrc.nist.gov/fips/fip180-1.txt -- Secure Hash Standard SHA-1
'
' This code is for private use only, and the security and/or encryption of the resulting
' hexadecimal value is not warrented or gaurenteed in any way.
'

Dim strEncode, strH(4)
Dim intPos


If len(strSecret) = 0 or len(strSecret) >= 2^61 then
    HashEncode = "0000000000000000000000000000000000000000"
    exit function
end if


'Initial Hex words are used for encoding Digest.  
'These can be any valid 8-digit hex value (0 to F)
strH(0) = "FB0C14C2"
strH(1) = "9F00AB2E"
strH(2) = "991FFA67"
strH(3) = "76FA2C3F"
strH(4) = "ADE426FA"

For intPos = 1 to len(strSecret) step 56

    strEncode = Mid(strSecret, intPos, 56) 'get 56 character chunks
    strEncode = WordToBinary(strEncode) 'convert to binary
    strEncode = PadBinary(strEncode) 'make it 512 bites
    strEncode = BlockToHex(strEncode) 'convert to hex value

    'Encode the hex value using the previous runs digest
    'If it is the first run then use the initial values above
    strEncode = DigestHex(strEncode, strH(0), strH(1), strH(2), strH(3), strH(4))

    'Combine the old digest with the new digest
    strH(0) = HexAdd(left(strEncode, 8), strH(0))
    strH(1) = HexAdd(mid(strEncode, 9, 8), strH(1))
    strH(2) = HexAdd(mid(strEncode, 17, 8), strH(2))
    strH(3) = HexAdd(mid(strEncode, 25, 8), strH(3))
    strH(4) = HexAdd(right(strEncode, 8), strH(4))

Next

'This is the final Hex Digest
HashEncode = strH(0) & strH(1) & strH(2) & strH(3) & strH(4)

End Function

I have converted it in C# as

public string HashEncode(string strSecret)
{
    string strEncode;
    string[] strH = new string [4];
    int intPos;

    if (strSecret.Length == 0 || strSecret.Length >= Int64.MaxValue)
    {
        return "0000000000000000000000000000000000000000";
        //break;
    }

    //Initial Hex words are used for encoding Digest.  
    //These can be any valid 8-digit hex value (0 to F)
    strH[0] = "FB0C14C2";
    strH[1] = "9F00AB2E";
    strH[2] = "991FFA67";
    strH[3] = "76FA2C3F";
    strH[4] = "ADE426FA";

    for(intPos = 1; intPos < strSecret.Length; intPos += 56)
    {
        strEncode = strSecret.Substring(intPos, strSecret.IndexOf(" ", 56));
        //strEncode = Mid(strSecret, intPos, 56); //get 56 character chunks
        strEncode = WordToBinary(strEncode); //convert to binary
        strEncode = PadBinary(strEncode); //make it 512 bites
        strEncode = BlockToHex(strEncode); //convert to hex value

        //Encode the hex value using the previous runs digest
        //If it is the first run then use the initial values above
        strEncode = DigestHex(strEncode, strH[0], strH[1], strH[2], strH[3], strH[4]);

        //Combine the old digest with the new digest
        //strH[0] = HexAdd(left(strEncode, 8), strH[0]);
        //strH[1] = HexAdd(mid(strEncode, 9, 8), strH[1]);
        //strH[2] = HexAdd(mid(strEncode, 17, 8), strH[2]);
        //strH[3] = HexAdd(mid(strEncode, 25, 8), strH[3]);
        //strH[4] = HexAdd(right(strEncode, 8), strH[4]);

        strH[0] = HexAdd(strEncode.Substring(0, 8), strH[0]);

        strH[1] = HexAdd(strEncode.Substring(9, 8), strH[1]);
        strH[2] = HexAdd(strEncode.Substring(17, 8), strH[2]);
        strH[3] = HexAdd(strEncode.Substring(25, 8), strH[3]);
        strH[4] = HexAdd(strEncode.Substring(strEncode.Length - 8,8),strH[4]);
    }
    //This is the final Hex Digest
    return strH[0] + strH[1] + strH[2] + strH[3] + strH[4];
}

It successfully compiled but not working. It gives exception at for loop as 'System.IndexOutOfRangeException was unhandled by user' Is anyone help me to solve this problem

2

There are 2 answers

4
Dave Doknjas On

Your 'for' loop is wrong for a couple of reasons: 1. the ending condition is incorrect - strSecret.Length has to be included if you start your indexing at 1. 2. when converting the legacy VB string functions, you have to be aware that they use 1-based indexing, while the .NET methods use 0-based indexing.

for (int intPos = 1; intPos <= strSecret.Length; intPos += 56)
{

    strEncode = strSecret.ToString().Substring(intPos - 1, 56); //get 56 character chunks
    strEncode = WordToBinary(strEncode); //convert to binary
    strEncode = PadBinary(strEncode); //make it 512 bites
    strEncode = BlockToHex(strEncode); //convert to hex value

    //Encode the hex value using the previous runs digest
    //If it is the first run then use the initial values above
    strEncode = DigestHex(strEncode, strH[0], strH[1], strH[2], strH[3], strH[4]);

    //Combine the old digest with the new digest
    strH[0] = HexAdd(strEncode.Substring(0, 8), strH[0]);
    strH[1] = HexAdd(strEncode.Substring(8, 8), strH[1]);
    strH[2] = HexAdd(strEncode.Substring(16, 8), strH[2]);
    strH[3] = HexAdd(strEncode.Substring(24, 8), strH[3]);
    strH[4] = HexAdd(strEncode.Substring(strEncode.Length - 8), strH[4]);

}

You also could use:

for (int intPos = 0; intPos < strSecret.Length; intPos += 56)
{

    strEncode = strSecret.ToString().Substring(intPos, 56); //get 56 character chunks
    ... (rest is identical)
}
0
Ansgar Wiechers On

The code is an implementation of the SHA-1 algorithm, correct? In that case:

using System.Security.Cryptography;
using System.Text;

string str = "foobar";

byte[] data = Encoding.ASCII.GetBytes(str);
SHA1 sha = new SHA1Managed();
byte[] hash = sha.ComputeHash(data);

Console.WriteLine(String.Concat(Array.ConvertAll(hash, x => x.ToString("X2"))));

Translation complete.