2016-11-14 130 views
1

我試圖解碼一個假定的十六進制字符串。在MS SQL Server(11.0.2100)中,數據的類型爲char(8)將十六進制字符串解碼爲4個映射到值的二進制映射的片段

在手冊中有對數據進行解碼的沒有明確的方式,但它記錄了它所包含的內容:

給出一個十六進制字符串即。 0001003F,長度爲4.低位字節 位於右側,高位字節位於左側。對於4個 'bytes',給出了將「比特」映射到某個真值的參考表。也給出了位順序是有在最右邊的是第1位的位0或位 ,......等等

表看起來是這樣的:

一號「字節」:

|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),則該位對應的狀態爲,位於

base_convert函數的幫助下,代碼將十六進制字符串$hex_str轉換爲整數$flags。循環迭代[0;31]範圍內的位數(從最低有效位開始)。 (1 << $bit)表達式是1的值向左移位01​​位。因此,如果位號$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)'。但是,一些DBMS實現可能會在'BINARY'字段(MySQL 8.0的計劃擴展)上按位操作。 –

+1

但是,您顯然通過以代碼複雜性的價格存儲十六進制字符來節省一些空間。您可以使用'BINARY'字段更好地壓縮它們; 'HEX(bin_field)'可以返回十六進制字符串以便在PHP中進一步處理。 –

相關問題