using System;
using System.Linq;
public class Test
{
private static void Assert (bool same)
{
Console.WriteLine(same);
}
private static byte[] ConvertHexToBytes(string input)
{
var result = new byte[(input.Length + 1) / 2];
var offset = 0;
if (input.Length % 2 == 1) {
// If length of input is odd, the first character has an implicit 0 prepended.
result[0] = (byte)Convert.ToUInt32(input[0] + "", 16);
offset = 1;
}
for (int i = 0; i < input.Length / 2; i++) {
result[i + offset] = (byte)Convert.ToUInt32(input.Substring(i * 2 + offset, 2), 16);
}
return result;
}
private static int HexToInt(char c)
{
switch (c) {
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
case 'a':
case 'A':
return 10;
case 'b':
case 'B':
return 11;
case 'c':
case 'C':
return 12;
case 'd':
case 'D':
return 13;
case 'e':
case 'E':
return 14;
case 'f':
case 'F':
return 15;
default:
throw new FormatException("Unrecognized hex char " + c);
}
}
private static readonly byte[,] ByteLookup = new byte[,]
{
// low nibble
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
// high nibble
{0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0}
};
private static byte[] ConvertHexToBytesX(string input)
{
var result = new byte[(input.Length + 1) >> 1];
int lastcell = result.Length - 1;
int lastchar = input.Length - 1;
for (int i = 0; i < input.Length; i++) {
result[lastcell - (i >> 1)] |= ByteLookup[i & 1, HexToInt(input[lastchar - i])];
}
return result;
}
private static void TestConversions() {
var inputs = new[] { "",
"0",
"10",
"f",
"0f",
"010",
"0ff",
"f2ab"
};
var i = 0;
Assert(ConvertHexToBytes(inputs[i++]).SequenceEqual(new byte[] { }));
Assert(ConvertHexToBytes(inputs[i++]).SequenceEqual(new byte[] { 0 }));
Assert(ConvertHexToBytes(inputs[i++]).SequenceEqual(new byte[] { 0x10 }));
Assert(ConvertHexToBytes(inputs[i++]).SequenceEqual(new byte[] { 0xf }));
Assert(ConvertHexToBytes(inputs[i++]).SequenceEqual(new byte[] { 0xf }));
Assert(ConvertHexToBytes(inputs[i++]).SequenceEqual(new byte[] { 0x0, 0x10 }));
Assert(ConvertHexToBytes(inputs[i++]).SequenceEqual(new byte[] { 0x0, 0xff }));
Assert(ConvertHexToBytes(inputs[i++]).SequenceEqual(new byte[] { 0xf2, 0xab }));
Assert(i == inputs.Length);
Console.WriteLine("rolfl");
i = 0;
Assert(ConvertHexToBytesX(inputs[i++]).SequenceEqual(new byte[] { }));
Assert(ConvertHexToBytesX(inputs[i++]).SequenceEqual(new byte[] { 0 }));
Assert(ConvertHexToBytesX(inputs[i++]).SequenceEqual(new byte[] { 0x10 }));
Assert(ConvertHexToBytesX(inputs[i++]).SequenceEqual(new byte[] { 0xf }));
Assert(ConvertHexToBytesX(inputs[i++]).SequenceEqual(new byte[] { 0xf }));
Assert(ConvertHexToBytesX(inputs[i++]).SequenceEqual(new byte[] { 0x0, 0x10 }));
Assert(ConvertHexToBytesX(inputs[i++]).SequenceEqual(new byte[] { 0x0, 0xff }));
Assert(ConvertHexToBytesX(inputs[i++]).SequenceEqual(new byte[] { 0xf2, 0xab }));
Assert(i == inputs.Length);
}
public static void Main()
{
TestConversions();
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uTGlucTsKCnB1YmxpYyBjbGFzcyBUZXN0CnsKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgQXNzZXJ0IChib29sIHNhbWUpCiAgICB7CiAgICAgICAgQ29uc29sZS5Xcml0ZUxpbmUoc2FtZSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIENvbnZlcnRIZXhUb0J5dGVzKHN0cmluZyBpbnB1dCkKICAgIHsKICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IGJ5dGVbKGlucHV0Lkxlbmd0aCArIDEpIC8gMl07CiAgICAgICAgdmFyIG9mZnNldCA9IDA7CiAgICAgICAgaWYgKGlucHV0Lkxlbmd0aCAlIDIgPT0gMSkgewogICAgICAgICAgICAvLyBJZiBsZW5ndGggb2YgaW5wdXQgaXMgb2RkLCB0aGUgZmlyc3QgY2hhcmFjdGVyIGhhcyBhbiBpbXBsaWNpdCAwIHByZXBlbmRlZC4KICAgICAgICAgICAgcmVzdWx0WzBdID0gKGJ5dGUpQ29udmVydC5Ub1VJbnQzMihpbnB1dFswXSArICIiLCAxNik7CiAgICAgICAgICAgIG9mZnNldCA9IDE7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXQuTGVuZ3RoIC8gMjsgaSsrKSB7CiAgICAgICAgICAgIHJlc3VsdFtpICsgb2Zmc2V0XSA9IChieXRlKUNvbnZlcnQuVG9VSW50MzIoaW5wdXQuU3Vic3RyaW5nKGkgKiAyICsgb2Zmc2V0LCAyKSwgMTYpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGludCBIZXhUb0ludChjaGFyIGMpCiAgICB7CiAgICAgICAgc3dpdGNoIChjKSB7CiAgICAgICAgICAgIGNhc2UgJzAnOiAKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICBjYXNlICcxJzogCiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgY2FzZSAnMic6IAogICAgICAgICAgICAgICAgcmV0dXJuIDI7CiAgICAgICAgICAgIGNhc2UgJzMnOiAKICAgICAgICAgICAgICAgIHJldHVybiAzOwogICAgICAgICAgICBjYXNlICc0JzogCiAgICAgICAgICAgICAgICByZXR1cm4gNDsKICAgICAgICAgICAgY2FzZSAnNSc6IAogICAgICAgICAgICAgICAgcmV0dXJuIDU7CiAgICAgICAgICAgIGNhc2UgJzYnOiAKICAgICAgICAgICAgICAgIHJldHVybiA2OwogICAgICAgICAgICBjYXNlICc3JzogCiAgICAgICAgICAgICAgICByZXR1cm4gNzsKICAgICAgICAgICAgY2FzZSAnOCc6IAogICAgICAgICAgICAgICAgcmV0dXJuIDg7CiAgICAgICAgICAgIGNhc2UgJzknOiAKICAgICAgICAgICAgICAgIHJldHVybiA5OwogICAgICAgICAgICBjYXNlICdhJzoKICAgICAgICAgICAgY2FzZSAnQSc6CiAgICAgICAgICAgICAgICByZXR1cm4gMTA7CiAgICAgICAgICAgIGNhc2UgJ2InOgogICAgICAgICAgICBjYXNlICdCJzoKICAgICAgICAgICAgICAgIHJldHVybiAxMTsKICAgICAgICAgICAgY2FzZSAnYyc6CiAgICAgICAgICAgIGNhc2UgJ0MnOgogICAgICAgICAgICAgICAgcmV0dXJuIDEyOwogICAgICAgICAgICBjYXNlICdkJzoKICAgICAgICAgICAgY2FzZSAnRCc6CiAgICAgICAgICAgICAgICByZXR1cm4gMTM7CiAgICAgICAgICAgIGNhc2UgJ2UnOgogICAgICAgICAgICBjYXNlICdFJzoKICAgICAgICAgICAgICAgIHJldHVybiAxNDsKICAgICAgICAgICAgY2FzZSAnZic6CiAgICAgICAgICAgIGNhc2UgJ0YnOgogICAgICAgICAgICAgICAgcmV0dXJuIDE1OwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEZvcm1hdEV4Y2VwdGlvbigiVW5yZWNvZ25pemVkIGhleCBjaGFyICIgKyBjKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgYnl0ZVssXSBCeXRlTG9va3VwID0gbmV3IGJ5dGVbLF0KICAgIHsKICAgICAgICAvLyBsb3cgbmliYmxlCiAgICAgICAgezB4MDAsIDB4MDEsIDB4MDIsIDB4MDMsIDB4MDQsIDB4MDUsIDB4MDYsIDB4MDcsCiAgICAgICAgIDB4MDgsIDB4MDksIDB4MGEsIDB4MGIsIDB4MGMsIDB4MGQsIDB4MGUsIDB4MGZ9LAogICAgICAgIC8vIGhpZ2ggbmliYmxlCiAgICAgICAgezB4MDAsIDB4MTAsIDB4MjAsIDB4MzAsIDB4NDAsIDB4NTAsIDB4NjAsIDB4NzAsCiAgICAgICAgIDB4ODAsIDB4OTAsIDB4YTAsIDB4YjAsIDB4YzAsIDB4ZDAsIDB4ZTAsIDB4ZjB9CiAgICB9OwoKICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBDb252ZXJ0SGV4VG9CeXRlc1goc3RyaW5nIGlucHV0KQogICAgewogICAgICAgIHZhciByZXN1bHQgPSBuZXcgYnl0ZVsoaW5wdXQuTGVuZ3RoICsgMSkgPj4gMV07CiAgICAgICAgaW50IGxhc3RjZWxsID0gcmVzdWx0Lkxlbmd0aCAtIDE7CiAgICAgICAgaW50IGxhc3RjaGFyID0gaW5wdXQuTGVuZ3RoIC0gMTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0Lkxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHJlc3VsdFtsYXN0Y2VsbCAtIChpID4+IDEpXSB8PSBCeXRlTG9va3VwW2kgJiAxLCBIZXhUb0ludChpbnB1dFtsYXN0Y2hhciAtIGldKV07CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBUZXN0Q29udmVyc2lvbnMoKSB7CiAgICAgICAgdmFyIGlucHV0cyA9IG5ld1tdIHsgIiIsCiAgICAgICAgICAgICAgICAiMCIsCiAgICAgICAgICAgICAgICAiMTAiLAogICAgICAgICAgICAgICAgImYiLAogICAgICAgICAgICAgICAgIjBmIiwKICAgICAgICAgICAgICAgICIwMTAiLAogICAgICAgICAgICAgICAgIjBmZiIsCiAgICAgICAgICAgICAgICAiZjJhYiIKICAgICAgICB9OwogICAgICAgIHZhciBpID0gMDsKICAgICAgICBBc3NlcnQoQ29udmVydEhleFRvQnl0ZXMoaW5wdXRzW2krK10pLlNlcXVlbmNlRXF1YWwobmV3IGJ5dGVbXSB7ICB9KSk7CiAgICAgICAgQXNzZXJ0KENvbnZlcnRIZXhUb0J5dGVzKGlucHV0c1tpKytdKS5TZXF1ZW5jZUVxdWFsKG5ldyBieXRlW10geyAwIH0pKTsKICAgICAgICBBc3NlcnQoQ29udmVydEhleFRvQnl0ZXMoaW5wdXRzW2krK10pLlNlcXVlbmNlRXF1YWwobmV3IGJ5dGVbXSB7IDB4MTAgfSkpOwogICAgICAgIEFzc2VydChDb252ZXJ0SGV4VG9CeXRlcyhpbnB1dHNbaSsrXSkuU2VxdWVuY2VFcXVhbChuZXcgYnl0ZVtdIHsgMHhmIH0pKTsKICAgICAgICBBc3NlcnQoQ29udmVydEhleFRvQnl0ZXMoaW5wdXRzW2krK10pLlNlcXVlbmNlRXF1YWwobmV3IGJ5dGVbXSB7IDB4ZiB9KSk7CiAgICAgICAgQXNzZXJ0KENvbnZlcnRIZXhUb0J5dGVzKGlucHV0c1tpKytdKS5TZXF1ZW5jZUVxdWFsKG5ldyBieXRlW10geyAweDAsIDB4MTAgfSkpOwogICAgICAgIEFzc2VydChDb252ZXJ0SGV4VG9CeXRlcyhpbnB1dHNbaSsrXSkuU2VxdWVuY2VFcXVhbChuZXcgYnl0ZVtdIHsgMHgwLCAweGZmIH0pKTsKICAgICAgICBBc3NlcnQoQ29udmVydEhleFRvQnl0ZXMoaW5wdXRzW2krK10pLlNlcXVlbmNlRXF1YWwobmV3IGJ5dGVbXSB7IDB4ZjIsIDB4YWIgfSkpOwogICAgICAgIEFzc2VydChpID09IGlucHV0cy5MZW5ndGgpOwogICAgICAgIENvbnNvbGUuV3JpdGVMaW5lKCJyb2xmbCIpOwogICAgICAgIGkgPSAwOwogICAgICAgIEFzc2VydChDb252ZXJ0SGV4VG9CeXRlc1goaW5wdXRzW2krK10pLlNlcXVlbmNlRXF1YWwobmV3IGJ5dGVbXSB7ICB9KSk7CiAgICAgICAgQXNzZXJ0KENvbnZlcnRIZXhUb0J5dGVzWChpbnB1dHNbaSsrXSkuU2VxdWVuY2VFcXVhbChuZXcgYnl0ZVtdIHsgMCB9KSk7CiAgICAgICAgQXNzZXJ0KENvbnZlcnRIZXhUb0J5dGVzWChpbnB1dHNbaSsrXSkuU2VxdWVuY2VFcXVhbChuZXcgYnl0ZVtdIHsgMHgxMCB9KSk7CiAgICAgICAgQXNzZXJ0KENvbnZlcnRIZXhUb0J5dGVzWChpbnB1dHNbaSsrXSkuU2VxdWVuY2VFcXVhbChuZXcgYnl0ZVtdIHsgMHhmIH0pKTsKICAgICAgICBBc3NlcnQoQ29udmVydEhleFRvQnl0ZXNYKGlucHV0c1tpKytdKS5TZXF1ZW5jZUVxdWFsKG5ldyBieXRlW10geyAweGYgfSkpOwogICAgICAgIEFzc2VydChDb252ZXJ0SGV4VG9CeXRlc1goaW5wdXRzW2krK10pLlNlcXVlbmNlRXF1YWwobmV3IGJ5dGVbXSB7IDB4MCwgMHgxMCB9KSk7CiAgICAgICAgQXNzZXJ0KENvbnZlcnRIZXhUb0J5dGVzWChpbnB1dHNbaSsrXSkuU2VxdWVuY2VFcXVhbChuZXcgYnl0ZVtdIHsgMHgwLCAweGZmIH0pKTsKICAgICAgICBBc3NlcnQoQ29udmVydEhleFRvQnl0ZXNYKGlucHV0c1tpKytdKS5TZXF1ZW5jZUVxdWFsKG5ldyBieXRlW10geyAweGYyLCAweGFiIH0pKTsKICAgICAgICBBc3NlcnQoaSA9PSBpbnB1dHMuTGVuZ3RoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBNYWluKCkKICAgIHsKICAgICAgICBUZXN0Q29udmVyc2lvbnMoKTsKICAgIH0KfQ==