private static byte[] EncodeLength(int length)
{
Debug.Assert(length >= 0);
byte low = unchecked((byte)length);
// If the length value fits in 7 bits, it's an answer all by itself.
if (length < 0x80)
{
return new[] { low };
}
// If the length is more than 0x7F then it is stored as
// 0x80 | lengthLength
// big
// endian
// length
// So:
// 0 => 0x00.
// 1 => 0x01.
// 127 => 0x7F.
// 128 => 0x81 0x80
// 255 => 0x81 0xFF
// 256 => 0x82 0x01 0x00
// 65535 => 0x82 0xFF 0xFF
// 65536 => 0x83 0x01 0x00 0x00
// ...
// int.MaxValue => 0x84 0x7F 0xFF 0xFF 0xFF
//
// Technically DER lengths can go longer than int.MaxValue, but since our
// encoding input here is an int, our output will be no larger than that.
if (length <= 0xFF)
{
return new byte[] { 0x81, low };
}
int remainder = length >> 8;
byte midLow = unchecked((byte)remainder);
if (length <= 0xFFFF)
{
return new byte[] { 0x82, midLow, low };
}
remainder >>= 8;
byte midHigh = unchecked((byte)remainder);
if (length <= 0xFFFFFF)
{
return new byte[] { 0x83, midHigh, midLow, low };
}
remainder >>= 8;
byte high = unchecked((byte)remainder);
// Since we know this was a non-negative signed number, the highest
// legal value here is 0x7F.
Debug.Assert(remainder < 0x80);
return new byte[] { 0x84, high, midHigh, midLow, low };
}