首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对可变位宽二进制块中的十进制值进行编码/解码

对可变位宽二进制块中的十进制值进行编码/解码
EN

Stack Overflow用户
提问于 2015-04-23 19:17:54
回答 1查看 142关注 0票数 2

我正在尝试为我正在设计的一个网络个人项目中的协议构建一个可变位宽的二进制编码器/解码器。我愚蠢的大脑完全不知道如何掌握可变位数的二进制编码/解码。我已经盯着同样的~18 SLOC大约四天了,我仍然感觉完全超出了我的深度。我确实觉得我应该能够掌握这一点,但不幸的是,当我试图跟踪不同的数字关系时,我的大脑随机地崩溃了:(

从理论上讲,我想要做的事情非常简单。我声明了一个位宽列表,以及我想要存储在该位宽中的值,如下所示:

代码语言:javascript
复制
[10 bits]: 1013
[1  bit ]: 1
[2  bits]: 3
[19 bits]: 51209

考虑到位宽,这些值将被逐步排序成一个二进制字符串,如下所示:

代码语言:javascript
复制
               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

上面粗体的位流是我在线路上传输的内容:

代码语言:javascript
复制
11111101  253  FD
01111000  120  78
11001000  200  C8
00001001    9  09

在另一端,我将列表{10, 1, 2, 19} (顶部表示的一组位宽)映射到我收到的字节序列,然后剩下我想要传输的原始值。

虽然这主要是一个通用的算法问题,并且任何特定语言的语义都可以说是无关紧要的,但我应该提一下我正在使用PHP来解决这个问题-我被困住的部分原因是我正在努力解决如何避免求助于字符串操作,PHP似乎偏向于鼓励人们偏爱字符串操作而不是适当的数字处理。然而,这个函数将(希望)以2到3位Mbps的速度处理数据,我希望例程尽可能快。(顺便说一句,我会使用另一种语言,但PHP是我最熟悉的一种>_>)

我确实理解二进制的基础知识,我应该强调的是,我确实有一个可以正常工作的编码器,我想(它向后输出二进制数据)-但我不知道我在这里做什么。我不是在问“我该如何写这个函数”,我是在问“我所做的事情的结构力学是什么,我该如何理解它。”

我还应该注意到,这个问题并不是一个简单的作业练习;它是针对我正在设计的个人软件项目中的网络库组件,希望能教会我有关网络、事件处理和并发性的知识。希望我能掌握我需要实现的所有其他东西……LOL

EN

回答 1

Stack Overflow用户

发布于 2015-04-23 23:37:35

为了给你一个小起点,这样的二进制解码器/编码器是如何看起来像这里的例子:

那么,这背后的概念是什么呢?

非常简单,我遍历您想要发送的每个数据,并将它们拆分成单个字节。举个例子:

代码语言:javascript
复制
data:    1013
bitMask:   10

所以我首先计算发送它需要多少字节。在这里,这将是每字节8比特的2字节。

在所有的准备和计算之后,逐字节和逐位地发送所有数据是很简单的!因此,如果我们以上面的例子为例,它将如下所示:

代码语言:javascript
复制
data:    1013  -> 0000'0011 1111'0101
bitMask:   10

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

因此,在发送数据(这里是浏览器中的输出)时,您是在反向显示数据!因为当你收到它的时候,你会把它改回来,然后你会得到正确的结果!

代码语言:javascript
复制
<?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]);

?>

输出:

代码语言:javascript
复制
10101111110000001000000011000000100100000001001100000000 //note output here is reversed!
Array ( [0] => 1013 [1] => 1 [2] => 3 [3] => 51209 )
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29821845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档