Битовый конвектор: Получить байтовый массив из строки
-
03-10-2019 - |
Вопрос
Когда у меня есть строка, как "0xd8 0xff 0xe0", я делаю
Text.Split(' ').Select(part => byte.Parse(part, System.Globalization.NumberStyles.HexNumber)).ToArray();
Но если я получил строку, как "0xd8ffe0", я не знаю, что делать?
Также я могу рекомендации, как написать байтовый массив в виде одной строки.
Решение
Вам нужно вычистить свою строку, прежде чем начать разбирать его. Сначала удалите ведущую 0x, а затем просто пропустите любые пробелы, которые вы перечисляете строку. Но использование LINQ для этого, вероятно, не самый лучший подход. Для одного, код не будет очень читаемо, и он будет трудно пройти, если вы отладки. Но также есть некоторые трюки, которые вы можете сделать, чтобы сделать преобразования Hex / Byte очень быстро. Например, не используйте Byte.parse, но вместо этого используйте индексирование массива, чтобы «посмотреть» соответствующее значение.
Некоторое время назад я реализовал класс Hexcencoding, который вытекает из базового класса кодирования, как Asciiencoding и UTF8ENCODING и т. Д. Использование его очень просто. Это довольно хорошо оптимизировано, что может быть очень важно в зависимости от размера ваших данных.
var enc = new HexEncoding();
byte[] bytes = enc.GetBytes(str); // convert hex string to byte[]
str = enc.GetString(bytes); // convert byte[] to hex string
Вот полный класс, я знаю, что это важно для поста, но я уделил комментарии Док.
public sealed class HexEncoding : Encoding
{
public static readonly HexEncoding Hex = new HexEncoding( );
private static readonly char[] HexAlphabet;
private static readonly byte[] HexValues;
static HexEncoding( )
{
HexAlphabet = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
HexValues = new byte[255];
for ( int i = 0 ; i < HexValues.Length ; i++ ) {
char c = (char)i;
if ( "0123456789abcdefABCDEF".IndexOf( c ) > -1 ) {
HexValues[i] = System.Convert.ToByte( c.ToString( ), 16 );
} // if
} // for
}
public override string EncodingName
{
get
{
return "Hex";
}
}
public override bool IsSingleByte
{
get
{
return true;
}
}
public override int GetByteCount( char[] chars, int index, int count )
{
return count / 2;
}
public override int GetBytes( char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex )
{
int ci = charIndex;
int bi = byteIndex;
while ( ci < ( charIndex + charCount ) ) {
char c1 = chars[ci++];
char c2 = chars[ci++];
byte b1 = HexValues[(int)c1];
byte b2 = HexValues[(int)c2];
bytes[bi++] = (byte)( b1 << 4 | b2 );
} // while
return charCount / 2;
}
public override int GetCharCount( byte[] bytes, int index, int count )
{
return count * 2;
}
public override int GetChars( byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex )
{
int ci = charIndex;
int bi = byteIndex;
while ( bi < ( byteIndex + byteCount ) ) {
int b1 = bytes[bi] >> 4;
int b2 = bytes[bi++] & 0xF;
char c1 = HexAlphabet[b1];
char c2 = HexAlphabet[b2];
chars[ci++] = c1;
chars[ci++] = c2;
} // while
return byteCount * 2;
}
public override int GetMaxByteCount( int charCount )
{
return charCount / 2;
}
public override int GetMaxCharCount( int byteCount )
{
return byteCount * 2;
}
} // class
Другие советы
Шестигранный
String
кbyte[]
:byte[] bytes = new byte[value.Length / 2]; for (int i = 0; i < value.Length; i += 2) { bytes[i / 2] = Convert.ToByte(value.Substring(i, 2), 16); }
Если у тебя есть
"0x"
В начале вы должны пропустить два байта.byte[]
или любогоIEnumerable<Byte>
-> ГекстераString
:return sequence.Aggregate(string.Empty, (result, value) => result + string.Format(CultureInfo.InvariantCulture, "{0:x2}", value));