Search code examples
c#type-conversionbytebit-shift

How can I convert a byte[] to an int in c# without using any System helper functions?


To convert a byte[] to an int, I would normally use BitConverter.ToInt32, but I'm currently working within a framework called UdonSharp that restricts access to most System methods, so I'm unable to use that helper function. I was able to do the reverse operation manually (converting int to byte[]) quite easily like so:

private byte[] GetBytes(int target)
{
    byte[] bytes = new byte[4];
    bytes[0] = (byte)(target >> 24);
    bytes[1] = (byte)(target >> 16);
    bytes[2] = (byte)(target >> 8);
    bytes[3] = (byte)target;
    return bytes;
}

But I'm struggling to get it working the other way around. Would greatly appreciate any help!


Solution

  • You can check the code here: https://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs

    #if BIGENDIAN
            public static readonly bool IsLittleEndian /* = false */;
    #else
            public static readonly bool IsLittleEndian = true;
    #endif
    
    [System.Security.SecuritySafeCritical] // auto-generated
    public static unsafe int ToInt32(byte[] value, int startIndex) {
      if (value == null) {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
      }
    
      if ((uint) startIndex >= value.Length) {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
      }
    
      if (startIndex > value.Length - 4) {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
      }
      Contract.EndContractBlock();
    
      fixed(byte * pbyte = & value[startIndex]) {
        if (startIndex % 4 == 0) { // data is aligned 
          return *((int * ) pbyte);
        } else {
          if (IsLittleEndian) {
            return ( * pbyte) | ( * (pbyte + 1) << 8) | ( * (pbyte + 2) << 16) | ( * (pbyte + 3) << 24);
          } else {
            return ( * pbyte << 24) | ( * (pbyte + 1) << 16) | ( * (pbyte + 2) << 8) | ( * (pbyte + 3));
          }
        }
      }
    }