2015-04-23 77 views
2

我正在嘗試在我正在設計的網絡化個人項目中爲協議構建一個可變位寬的二進制編碼器/解碼器......並且我的愚蠢大腦完全卡住了了解如何掌握可變比特二進制編碼/解碼。我一直在盯着同樣的〜18 SLOC,現在已經有四天了,我仍然感覺完全沒有了我的深度。我確實認爲我應該能夠把握這一點,但不幸的是,當我試圖追蹤不同的數字關係時,我的大腦隨機地排除了:(對可變位二進制塊中的十進制值進行編碼/解碼

理論上,我想要做的事非常簡單:我聲明一個位寬列表,和值我想那位寬內存儲,就像這樣:

[10 bits]: 1013 
[1 bit ]: 1 
[2 bits]: 3 
[19 bits]: 51209 

服用bitwidths考慮,該值將逐步測序成二進制字符串,像這樣:

   1 bit 
       | 2 bits 
       | || 
    /-10 bits--\ | \/ /------ 19 bits ------\ 
    12345678 12 3 45 678 12345678 12345678 
    11111101 01 1 11 000 11001000 00001001 
    \----------/ | \/ \---------------------/ 
     1012  1 3   51209 

在比特流上面的大膽是我傳遞下來的線材:

11111101 253 FD 
01111000 120 78 
11001000 200 C8 
00001001 9 09 

在另一端,我映射列表{10, 1, 2, 19}我收到(設定在頂部表示bitwidths)針對字節的順序,然後讓我與原來的設定值的我想要傳送。

儘管這主要是一個通用的算法問題,任何特定語言的語義都可以說是無關緊要的,但我應該提及,我正在使用PHP來實現這一點 - 而且我堅持的部分原因是我試圖找出如何避免使用字符串操作,PHP似乎傾向於鼓勵人們傾向於正確的數字處理。然而,這個功能將(希望)以2到3位Mbps的速度處理數據,並且我希望程序儘可能快。 (順便說一下,我會使用另一種語言,但PHP是我知道的最多> _>)

我明白二進制的基礎知識,我應該強調我確實有一個工作的編碼器,我認爲(它向後輸出二進制數據) - 但我不知道我在這裏做什麼。我並不是問「我怎麼寫這個函數」,我問「我在做什麼的結構力學,我怎麼才能把握這個。」

我還應該指出,這個問題並不是一個簡單的變相作業練習;它適用於我設計的個人軟件項目中的網絡庫組件,希望能夠教會我有關網絡,事件處理和併發性的知識。希望我能掌握所有其他的事情,我需要實現...笑

+1

你能分享你試過嗎? –

+1

請添加你已經嘗試/嘗試並顯示你正在尋找的東西(具體如你所描述的那樣)! – Rizier123

回答

2

爲了給你一個小起始點這樣的二進制譯碼器/編碼器如何能像這裏的例子:那麼現在有什麼

背後的概念?

很簡單,我循環你想發送的每個數據並將它們分成單個字節。舉個例子:

data: 1013 
bitMask: 10 

所以我首先計算髮送它需要多少字節。這裏這將是2字節每字節8位。

經過所有的準備和計算,它可以直接發送所有數據,逐字節地逐位發送!所以,如果我們從上面的例子中,這將是這個樣子:

data: 1013 -> 0000'0011 1111'0101 
bitMask: 10 

total amount of bytes: 2 
1. byte = 1111'0101 
2. byte = 0000'0011 

所以當發送數據(這裏輸出在瀏覽器),你在倒車顯示的數據!因爲當你收到它時,你正在改變它,你會得到正確的結果!

<?php 

    class binaryCoder { 

     /* Properties */ 
     public $data; // <-- save/receive data into this property 
     public $bitMask = []; 
     private $byteCount = 0x00; 

     /* Constructor */ 
     public function __construct() { 


     } 

     /* Methods */ 
     public function writeData(array $data, array $bitMask) { 

      $this->data = $data; 
      $this->bitMask = $bitMask; 
      $this->byteCount = array_reduce($this->bitMask, function($byteCount, $bits){ 
       return $byteCount + ceil($bits/8); 
      }, 0x00); 


      foreach(array_combine($this->bitMask, $this->data) as $mask => $data) { 
       for($byteCounter = 0; $byteCounter < ceil($mask/8); $byteCounter++) { 
        $this->writeByte($data >> ($byteCounter*8)); 
       } 
      } 

     } 

     public function readData(array $bitMask) { 
      $this->bitMask = $bitMask; 
      $byte = 0x00; 


      foreach($this->bitMask as $key => $mask) { 
       $message[$key] = ""; 
       for($byteCounter = 0; $byteCounter < ceil($mask/8); $byteCounter++, $byte++) { 
        $message[$key] = sprintf("%08d", $this->readByte($byte*8)) . $message[$key]; 
       } 
      } 

      $message = array_map("bindec", $message); 
      print_r($message); 

     } 

     private function writeByte($byte) { 
      for($bitCount = 0; $bitCount < 8; $bitCount++) { 
       $this->writeBit((bool)($byte & (1 << $bitCount))); 
      } 
     } 

     private function readByte($bytePosition) { 
      $byte = 0x00; 

      for($bitCount = 0; $bitCount < 8; $bitCount++) { 
       $byte |= (int)$this->readBit($bytePosition+$bitCount) << $bitCount; 
      } 
      return decbin($byte); 
     } 

     private function writeBit($bit) { 
      echo ($bit?1:0); // --> send/write data to dest. (Note it's reversed!) 
     } 

     private function readBit($bit) { 
      return $this->data[$bit]; 
     } 


    } 


    /* Testing */ 
    $binaryTransmitter = new binaryCoder(); 
    $binaryTransmitter->writeData([1013, 1, 3, 51209], [10, 1, 2, 19]); 
    $binaryTransmitter->data = "10101111110000001000000011000000100100000001001100000000"; //received data 
    $binaryTransmitter->readData([10, 1, 2, 19]); 

?> 

輸出:

10101111110000001000000011000000100100000001001100000000 //note output here is reversed! 
Array ([0] => 1013 [1] => 1 [2] => 3 [3] => 51209) 
相關問題