2016-11-14 14 views
1

Я пытаюсь декодировать якобы шестую строку. В MS SQL Server (11.0.2100) данные имеют тип char(8).Декодирование шестнадцатеричной строки на 4 части, которая отображается на двоичную карту значений

В руководствах не был четким способом декодирования данных, но документы, что он содержит:

Учитывая шестнадцатеричную строку, т.е.. 0001003F с длиной 4. Нижний байт находится справа, старший байт слева. Для каждого из 4 'bytes' была дана ссылочная таблица, которая отображает бит для определенного значения правды . Немного заказ также учитывая, имеющий бит 0 или битого в самом правом быть 1-й бита, ... и т.д.

таблица выглядит следующим образом:

первых «байты»:

|Bit Order | Description | 1    | 0    | trigger  | 
|-----------|---------------|-------------------|-------------------|---------------| 
|BIT0  | state foo  | state foo is ON | State foo is OFF | high level | 
|BIT1  | state bar  | in state bar  | not in state bar | high level | 
|         ... 
|BIT7  | state bazz | in state bazz  | not in state bazz | high level | 

(еще 3 таблицы следует для следующих 3 других «байт в ..., каждый из 4» байт-х предположительно имеет 8 равное количество „биты“)

я думал, способ декодирования этой информации является разделение шестнадцатеричной строки int O 4 части и преобразовывать их в виде бинарной строки шириной фиксировали из 8.

В PHP, взятый пример шестигранной «0001003F», первый байт был «3F», имея преобразованы в двоичный, 0011 1111 (пространство для ясности). Затем было установлено, что значение для первого байта:

'state foo is on', 'in state bar', ..., 'not in state bazz'.

Я также пытался: hex2bin("0001003F"), но он выводит strin(4) " # ".

Это правильный способ декодирования этих данных?

(прошу прощения, если теги неверны.)

ответ

1

С 4 байта вписываться в хранилище для integer type практически на всех платформах (32-бит и выше), вы можете преобразовать шестнадцатеричный строку целое число, а затем использовать bitwise operators, чтобы проверить, если определенный бит установлен:

$hex_str = '0001003F'; 
$flags = base_convert($hex_str, 16, 10); 

foreach (range(0, 31) as $bit) { 
    printf("Bit %d: %d\n", $bit, (bool) ($flags & (1 << $bit))); 
} 

Выход

Bit 0: 1 
Bit 1: 1 
Bit 2: 1 
Bit 3: 1 
Bit 4: 1 
Bit 5: 1 
Bit 6: 0 
... 
Bit 15: 0 
Bit 16: 1 
Bit 17: 0 
... 
Bit 31: 0 

Если бит $bit установлен (1), то состояние, соответствующее этому биту, равно по адресу.

Код преобразует шестнадцатеричную строку $hex_str в целое число $flags с помощью функции base_convert. Цикл выполняет итерацию номеров бит в диапазоне [0;31] (начиная с младшего значащего разряда). Выражение (1 << $bit) - это значение 1, сдвинутое влево на $bit бит.Таким образом, если установлен бит $bit, то результат побитовой операции И является ненулевым целым числом. Результат приводится к типу boolean для получения 1, если результат отличен от нуля, а 0 в противном случае.

Легко видеть, что вы можете проверить количество битов с одним побитового И операции, например:

// Check if at least one of three bits is set, 3rd, 10th, or 11th 
$mask = (1 << 3) | (1 << 10) | (1 << 11); 
if ($flags & $mask) 
    printf("At least one of the bits from mask 0x%x is set\n", $mask); 

Выходной

At least one of the bits from mask 0xc08 is set 
+0

Мое решение было очень похоже на ваш ответ. Существует ли такое кодирование/декодирование на практике? Я действительно не знаком с этой схемой кодирования/декодирования. –

+0

@ javiniar.leonard, это зависит от проблемы. В частности, я не думаю, что 'CHAR (8)' является хорошим выбором для бит-маски. Если точно известно, что число бит не будет больше 64, я бы предпочел использовать 'BIGINT'. Если свойства состояний, вероятно, будут расти, или состояния могут иметь отношения с другими таблицами в будущем, я бы создал таблицу для состояний и таблицу для состояний объектов, таких как «obj_states (object_id, state_id)». Однако некоторые реализации СУБД могут содержать побитовые операции над полями BINARY (плановое расширение для MySQL 8.0). –

+1

Но вы, очевидно, сохраняете некоторое пространство, сохраняя шестнадцатеричные символы по цене сложности кода. Вы можете сжать их лучше с помощью поля «BINARY»; 'HEX (bin_field)' может вернуть шестую строку для дальнейшей обработки в PHP. –

 Смежные вопросы

  • Нет связанных вопросов^_^