Работа с hex значениями в C#

Недавно мне неоднократно понадобилось работать с файлами, при этом выполнять в них поиск по байтам. Особенностью являлось то, что пользователь вводил значения в шестнадцатеричной форме. Проще всего когда это 1 байт, если нужно найти последовательность байт введенных в шестнадцатеричной форме? Я написал небольшой статистический класс для этого. Он может переводить строку, содержащую hex, в массив байт и обратно. Кроме того, реализована возможность перевести строку, содержащую hex в ее десятеричный числовой эквивалент.

Кого заинтересовало — прошу под кат.

Сначала нужно было определится со структурой класса. Основная задача — перевод из десятеричной в шестнадцатеричную и обратно. Я решил, что меня устроит статистический класс, со статистическими методами, поскольку хранить какие-то данные не нужно. Для начала я решил написать функцию нормализации hex значений. О чем я конкретно говорю? Что бы легче было работать со строкой, как с байтами в hex, ее длина должна быть четной, поскольку максимальное значение байта — 255(256 значений, 8 бит, 2^8), в шестнадцатеричной форме это FF. То есть каждый байт занимает 2 символа в строке. Но может быть значение например «F25AC». Для нормализации, в начало следует добавить ноль, что бы вышло «0F 25 AC», отсюда ясно видно, сколько байт и чему каждый равен. Функция вышла вот такая:

        public static string CheckHex(string input)
        {
            string result = input;
            if (input.Length % 2 != 0)
                result = '0' + result;
            return result;
        }

Принцип работы прост: если длина входной строки не четная — значит нужно добавить ноль в начале. После написания этой функции, я решил сделать 2 функции которые переводят из шестнадцатеричной в десятеричную и наоборот лишь по одному байту. Первая переводит hex в dec:

        public static byte Hex2Dec(string input)
        {
            byte result = 0;
            result = byte.Parse(input, System.Globalization.NumberStyles.HexNumber);
            return result;
        }

Я использую встроенные средства .NET, что бы перевести hex строку в число byte. Следующий метод работает наоборот, из числа byte делает строку с hex:

        public static string Dec2Hex(byte input)
        {
            string result = string.Empty;
            result = input.ToString("X");
            return CheckHex(result);
        }

Опять таки же — встроенные средства .NET и моя функция нормализации. После чего я решил, что мне может понадобиться из hex числа, размером более 1 байта, получить десятеричное число. Поэтому решил дописать еще два метода. Первый переводит строку hex в десятеричный формат числа типа long(для больших значений):

        public static long Hex2DecL(string input)
        {
            long result = 0;
            result = long.Parse(input, System.Globalization.NumberStyles.HexNumber);
            return result;
        }

Работает аналогично тому, который переводит всего 1 байт. Следующий выполняет обратную операцию.

        public static string Dec2HexL(long input)
        {
            string result = string.Empty;
            result = input.ToString("X");
            return CheckHex(result);
        }

Теперь используя описанные методы, я создал еще 2 которые перегоняют hex строку в массив байт и наоборот. Вот первый из них:

        public static byte[] HexStr2DecArr(string input)
        {
            string normalHex = CheckHex(input);
            byte[] result = new byte[normalHex.Length / 2];
            for (int i = 0, first = 0, second = 1; i < result.Length; ++i, first = first + 2, second = second + 2)
                result[i] = Hex2Dec(normalHex[first].ToString() + normalHex[second].ToString());
            return result;
        }

Каждые 2 символа строки метод преобразовывает в очередной элемент массива байт. Вот теперь видно, зачем нужен метод CheckHex. Если бы не он, строка обработалась бы неправильно. Теперь обратный метод:

        public static string DecArr2HexStr(byte[] input)
        {
            string result = string.Empty;
            foreach (byte _byte in input)
                result += CheckHex(Dec2Hex(_byte));
            return result;
        }

Он еще проще, каждый байт преобразовывается в hex и добавляется в строку. Вот собственно и все. Задавайте свои ответы, удачи!

Комментарии 5

  • Перевод byte[] в Hex уже имется в .NET’е от мелких(http://msdn.microsoft.com/ru-ru/library/microsoft.visualbasic.conversion.hex.aspx), а вот обратного для группы байтов я не фиксировал

  • Dec2Hex:
    Думаю что не совсем правильно: result = input.ToString(«X»);
    Наверно должно быть так: result = input.ToString(«X2»);

  • При составлении программы под compact_fraework_2.0 считать бинарный файл получается но только в десятичной кодировке.Прошу поделится советом и примером применения приведённых в этой статье методов.

  • unsigned char Hi,Low;
    void dechex2(unsigned char c)
    {
    unsigned char hi,low;
    unsigned char c_Array[] = {‘0′,’1′,’2′,’3′,’4′,’5′,’6′,’7′,’8′,’9′,’A’,’B’,’C’,’D’,’E’,’F’,’x’};
    hi=(c & 0xf0 )>>4;
    low=c & 0x0f;

    Hi=c_Array[hi];

    Low=c_Array[low];

    }

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *