views:

27

answers:

1

I've picked up some old code that I need to work with and I have the following function in C

int pem64_decode_bytes(const char *intext,
                       int nchars,
                       unsigned char *outbytes)
{
  unsigned char *outbcopy = outbytes;
  while (nchars >= 4) {
    char 
      c1 = intext[0], 
      c2 = intext[1],
      c3 = intext[2],
      c4 = intext[3];
    int 
      b1 = pem64_dict_offset(c1), 
      b2 = pem64_dict_offset(c2),
      b3 = pem64_dict_offset(c3),
      b4 = pem64_dict_offset(c4);

    if ((b1 == -1) || (b2 == -1) || (b3 == -1) || (b4 == -1))
      return outbytes - outbcopy;

    *(outbytes++) = (b1 << 2) | (b2 >> 4);

    if (c3 != FILLERCHAR)
      *(outbytes++) = ((b2 & 0xf) << 4) | (b3 >> 2);
    if (c4 != FILLERCHAR)
      *(outbytes++) = ((b3 & 0x3) << 6) | b4;

    nchars -= 4;
    intext += 4;
  }

  return outbytes - outbcopy;
}

It should decode a packet of data that has been encoded. Does anyone know if this is a standard function? I need to convert this to C#, I'm not a C coder does anyone know of any samples that do this?

Edit

=======

public static List<byte> pem64_decode_bytes(string InText, int NumberOfBytes)
    {
        var RetData = new List<byte>();

        while (NumberOfBytes >= 4)
        {
            char c1 = InText[0];
            char c2 = InText[1];
            char c3 = InText[2];
            char c4 = InText[3];

            int b1 = pem64_dict_offset(c1);
            int b2 = pem64_dict_offset(c2);
            int b3 = pem64_dict_offset(c3);
            int b4 = pem64_dict_offset(c4);

            if (b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1)
            {
                return RetData;
            }

            (outbytes)++.Deref = b1 << 2 | b2 >> 4;
            if (c3 != FILLERCHAR)
            {
                (outbytes)++.Deref = (b2 & 0xf) << 4 | b3 >> 2;
            }
            if (c4 != FILLERCHAR)
            {
                (outbytes)++.Deref = (b3 & 0x3) << 6 | b4;
            }

            NumberOfBytes -= 4;
        }

        return RetData;
    }
A: 

Do you have the source for pem64_dict_offset too? I don't recognise this as a standard function, although it looks rather like Base64 decoding.

If so, it probably wouldn't be very hard to convert to C#.

The *(outbytes++) thing which is probably terrifying to a non-C programmer is just appending a byte to a block of bytes.

A C# analogy would be:

List<Byte> outbytes = new List<Byte>()
outbytes.Add(the new byte)

The 'return outbytes-outbcopy' would become 'return outbytes.Count' (Although it would be more typical in C# just to return the list, rather than require the caller to allocate it for you.

Will Dean
@will dean, thanks! I've updated the main post with where I am up to. Your right that bit scared me a little, however I've still not sure how to convert the remaining part of that line (outbytes)++.Deref = b1 << 2 | b2 >> 4;
Pino
Don't convert it - it should compile as C#, though you might need to cast back to (Byte) But I would always write it as (b1 << 2) | (b2 >> 4). The >> operators are bit shifts, and the | is a bitwise-OR. Their syntax is the same for C and C#
Will Dean
Actually, you're also not moving through the input string. In the C example, the inText+=4 moves the inText pointer on four chars each time, so that inText[0],etc, access a different four bytes each time. You'll need to do this yourself with an integer offset variable which starts at zero and gets incremented by four each time. You could replace the 'while' with this: 'for(int offset = 0; offset < NumberOfBytes; offset += 4)'
Will Dean
And btw, your naming/casing conventions are horrible, sorry. The Framework Design Guidelines is a really good book.
Will Dean
@will dean Naming conventions are not mine as I stated I didnt write the function.
Pino
It was the C# version I was talking about.
Will Dean