Расшифровка шестнадцатеричного формата - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть эта строка в шестнадцатеричном: "0000803F00000000000000B4B410D1A90000803FB41051B500000034B41051350000803F000000000000000000C05B400000000000C06B400000000000D07440"

и я знаю, что в нем содержится:

(1, 0, -1.192093e-007),

(- 9,284362e-014, 1, -7,788287e-007),

(1.192093e-007, 7.788287e-007, 1),

(111, 222, 333).

И да, это матрица преобразования!

Декодирование первых 72 символов (8 символов на число) было тривиальным, вам нужно только разделить на 8 и использовать формат IEEE с плавающей запятой, т.е. 0x0000803F = 1.0f

Таким образом, у нас все еще есть "000000000000000000C05B400000000000C06B400000000000D07440", который содержит четвертый вектор, но я никогда не видел такой числовой кодификации.

Есть хоть что-нибудь по этому поводу?

1 Ответ

0 голосов
/ 26 апреля 2018

Похоже, это 8-байтовые числа с плавающей запятой IEEE, начиная с байта 40. Таким образом, макет:

  • Байты 0-11: первый вектор, 3 числа одинарной точности
  • байты 12-23: второй вектор, 3 числа одинарной точности
  • байты 25-35: третий вектор, 3 числа одинарной точности
  • байты 36-39: не используется?(Заполнение?)
  • Байты 40-63: четвертый вектор, 3 числа с двойной точностью

Приведенный ниже код показывает пример анализа этого в C #.Вывод кода:

(1, 0, -1.192093E-07)
(-9.284362E-14, 1, -7.788287E-07)
(1.192093E-07, 7.788287E-07, 1)
(111, 222, 333)

Пример кода:

using System;

class Program
{
    static void Main(string[] args)
    {
        string text = "0000803F00000000000000B4B410D1A90000803FB41051B500000034B41051350000803F000000000000000000C05B400000000000C06B400000000000D07440";
        byte[] bytes = ParseHex(text);

        for (int i = 0; i < 3; i++)
        {
            float x = BitConverter.ToSingle(bytes, i * 12);
            float y = BitConverter.ToSingle(bytes, i * 12 + 4);
            float z = BitConverter.ToSingle(bytes, i * 12 + 8);
            Console.WriteLine($"({x}, {y}, {z})");
        }

        // Final vector
        {
            double x = BitConverter.ToDouble(bytes, 40);
            double y = BitConverter.ToDouble(bytes, 48);
            double z = BitConverter.ToDouble(bytes, 56);
            Console.WriteLine($"({x}, {y}, {z})");
        }
    }

    // From https://stackoverflow.com/a/854026/9574109
    public static byte[] ParseHex(string hex)
    {
        int offset = hex.StartsWith("0x") ? 2 : 0;
        if ((hex.Length % 2) != 0)
        {
            throw new ArgumentException("Invalid length: " + hex.Length);
        }
        byte[] ret = new byte[(hex.Length-offset)/2];

        for (int i=0; i < ret.Length; i++)
        {
            ret[i] = (byte) ((ParseNybble(hex[offset]) << 4) 
                             | ParseNybble(hex[offset+1]));
            offset += 2;
        }
        return ret;
    }        

    static int ParseNybble(char c)
    {
        if (c >= '0' && c <= '9')
        {
            return c-'0';
        }
        if (c >= 'A' && c <= 'F')
        {
            return c-'A'+10;
        }
        if (c >= 'a' && c <= 'f')
        {
            return c-'a'+10;
        }
        throw new ArgumentException("Invalid hex digit: " + c);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...