Anders
Anders

Reputation: 12570

Need a little more help converting a CRC function from VB.NET to C#

I probably should have just put all this in one question, sorry for that :(

Second error

Ok, this should be the end of errors (hopefully):

private static string getCRC(string input, bool appendDate)
{
    string toEnc = string.Format("{0}{1}", input, appendDate == true ? string.Format("{0:yyyyMMdd}", System.DateTime.Now) : "");
    System.IO.MemoryStream mStream = new System.IO.MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(toEnc), false);
    
    CRC32 oCRC = new CRC32();
    return oCRC.GetCrc32(((System.IO.Stream)mStream)).ToString();
}

Error is on the return line:

Compiler Error Message: CS1502: The best overloaded method match for 'CRC.CRC32.GetCrc32(ref System.IO.Stream)' has some invalid arguments

Here is the function it is referring to:

public UInt32 GetCrc32(ref System.IO.Stream stream)
{
    //Dim crc32Result As Integer = &HFFFFFFFF
    UInt32 crc32Result = UInt32.MaxValue;

    try
    {

        byte[] buffer = new byte[BUFFER_SIZE];
        int readSize = BUFFER_SIZE;

        int count = stream.Read(buffer, 0, readSize);
        int i;
        UInt32 iLookup;
        //Dim tot As Integer = 0
        while ((count > 0))
        {
            for (i = 0; i <= count - 1; i++)
            {
                iLookup = (crc32Result & 0xff) ^ buffer[i];
                //crc32Result = ((crc32Result And &HFFFFFF00) \ &H100) And &HFFFFFF                     ' nasty shr 8 with vb :/
                crc32Result = ((UInt32)((crc32Result & 4294967040L) / 256) & UInt32.MaxValue);
                // nasty shr 8 with vb :/
                crc32Result = crc32Result ^ crc32Table[iLookup];
            }
            count = stream.Read(buffer, 0, readSize);
        }
    }
    catch (Exception ex)
    {
        HttpContext.Current.Response.Output.Write(string.Format("{0}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace));
        System.Diagnostics.Debugger.Break();
    }

    return (~crc32Result);

}

As you can see I tried to cast the memorystream as a stream, but I don't think it liked that too much.

First error

(solved here)

If you have not seen my last couple of questions, I have a CRC function written in VB.NET. I used an online converter to convert it over to C#. Here is the original VB code:

Public Sub New()
    Dim dwPolynomial As UInt32 = 3988292384
    Dim i As Integer, j As Integer

    ReDim crc32Table(256)
    Dim dwCrc As UInt32

    For i = 0 To 255
        dwCrc = i
        For j = 8 To 1 Step -1
            If (dwCrc And 1) Then
                dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
                dwCrc = dwCrc Xor dwPolynomial
            Else
                dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
            End If
        Next j
        crc32Table(i) = dwCrc
    Next i
End Sub

Here is my converted code. I fixed a few of the errors I was having but there are few more that I cannot figure out:

public CRC32()
{
    UInt32 dwPolynomial = ((UInt32)3988292384L);
    int i;
    int j;

    UInt32[] crc32Table;
    crc32Table = new UInt32[256];
    UInt32 dwCrc;

    for (i = 0; i <= 255; i++)
    {
        dwCrc = ((UInt32)i);
        for (j = 8; j >= 1; j -= 1)
        {
            if ((dwCrc & 1))
            {
                dwCrc = ((dwCrc & 0xfffffffe) / 2L) & 0x7fffffff;
                dwCrc = dwCrc ^ dwPolynomial;
            }
            else
            {
                dwCrc = ((dwCrc & 0xfffffffe) / 2L) & 0x7fffffff;
            }
        }
        crc32Table[i] = dwCrc;
    }
}

The first error is on this line:

Compiler Error Message: CS0030: Cannot convert type 'uint' to 'bool'

if ((dwCrc & 1))

Should I be comparing these two values with a different operator? I am not too sure about why the & operator is there to be honest.

Thanks SO.

Upvotes: 2

Views: 1370

Answers (6)

Paul Sasik
Paul Sasik

Reputation: 81547

With the help of ReSharper I got your converted code to compile.

Try this out:

    public void CRC32()
    {
        UInt32 dwPolynomial = ((UInt32) 3988292384L);
        int i;
        int j;

        UInt32[] crc32Table;
        crc32Table = new UInt32[256];
        UInt32 dwCrc;

        for (i = 0; i <= 255; i++)
        {
            dwCrc = ((UInt32) i);
            for (j = 8; j >= 1; j -= 1)
            {
                if ((dwCrc & 1) != 0u)
                {
                    dwCrc = (uint) (((dwCrc & 0xfffffffe)/2L) & 0x7fffffff);
                    dwCrc = dwCrc ^ dwPolynomial;
                }
                else
                {
                    dwCrc = (uint) (((dwCrc & 0xfffffffe)/2L) & 0x7fffffff);
                }
            }

            crc32Table[i] = dwCrc;
        }
    }

Upvotes: 1

JMarsch
JMarsch

Reputation: 21751

Looks like a lot of these responses address your first error. The problem with your second error is that your GetCrc method expects the stream to be passed by reference (the ref keyword).

In C#, If the method defines a parameter by reference, you have to explicitly pass it by reference when you call it. So add the ref keyword when you call your GetCrcMethod:

(also, you don't need the cast -- MemoryStream inherits from Stream)

return oCrc.GetCrc32(ref mStream).ToString();

One other consideration: Unless you plan to change which strem mStream references, you don't need to make a byRef parameter. Unless you plan to assign a value to stream (stream = new stream, or stream = null), it is more correct to just remove the ref keyword from the method declaration altogether.

Upvotes: 0

Mark Brackett
Mark Brackett

Reputation: 85685

For your 2nd problem (which would have gotten more traffic if you posted it as a 2nd question):

The best overloaded method match for 'CRC.CRC32.GetCrc32(ref System.IO.Stream)' has some invalid arguments

Remove the ref modifier on the C# code:

public UInt32 GetCrc32(ref System.IO.Stream stream)

becomes

public UInt32 GetCrc32(System.IO.Stream stream)

I suspect the original VB.NET had ByRef where it wasn't necessary - I don't see you reassigning the value of stream anywhere.

Alternatively, call it with a ref parameter:

return oCRC.GetCrc32(ref mStream).ToString();

Upvotes: 2

Sean
Sean

Reputation: 4470

That particular line is bitwise-ANDing dwCrc and 1, which is just 0x01. So basically, it's checking that dwCrc's least significant bit is a 1, not a 0. If it is, the result will be 1. If not, the result is 0. In VB, integers are converted to bools automatically (0 -> false, everything else -> true). In C#, you have to compare it with a value explicitly

if ((dwCrc & 1) != 0) ...

(Also note that the ( & 1) is presumably needed, since it is checking for only one particular bit. If dwCrc == 0x02, then the original test will fail, as will the converted one. So doing something like

if(dwCrc != 0) ...

would be wrong, although it may not seem so at first.)

Upvotes: 0

Claus J&#248;rgensen
Claus J&#248;rgensen

Reputation: 26355

C# do not assume that 0 is equal false, and that 1 is equal true.

Thus

if ((dwCrc & 1) == 1) { }

Would be what you need.

Upvotes: 2

Pavel Minaev
Pavel Minaev

Reputation: 101665

There's no implicit integer-to-boolean conversion in C#. You have to compare against 0 explicity:

if ((dwCrc & 1) != 0) ...

Upvotes: 7

Related Questions