我正在尝试为我正在设计的一个网络个人项目中的协议构建一个可变位宽的二进制编码器/解码器。我愚蠢的大脑完全不知道如何掌握可变位数的二进制编码/解码。我已经盯着同样的~18 SLOC大约四天了,我仍然感觉完全超出了我的深度。我确实觉得我应该能够掌握这一点,但不幸的是,当我试图跟踪不同的数字关系时,我的大脑随机地崩溃了:(
从理论上讲,我想要做的事情非常简单。我声明了一个位宽列表,以及我想要存储在该位宽中的值,如下所示:
[10 bits]: 1013
[1 bit ]: 1
[2 bits]: 3
[19 bits]: 51209考虑到位宽,这些值将被逐步排序成一个二进制字符串,如下所示:
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} (顶部表示的一组位宽)映射到我收到的字节序列,然后剩下我想要传输的原始值。
虽然这主要是一个通用的算法问题,并且任何特定语言的语义都可以说是无关紧要的,但我应该提一下我正在使用PHP来解决这个问题-我被困住的部分原因是我正在努力解决如何避免求助于字符串操作,PHP似乎偏向于鼓励人们偏爱字符串操作而不是适当的数字处理。然而,这个函数将(希望)以2到3位Mbps的速度处理数据,我希望例程尽可能快。(顺便说一句,我会使用另一种语言,但PHP是我最熟悉的一种>_>)
我确实理解二进制的基础知识,我应该强调的是,我确实有一个可以正常工作的编码器,我想(它向后输出二进制数据)-但我不知道我在这里做什么。我不是在问“我该如何写这个函数”,我是在问“我所做的事情的结构力学是什么,我该如何理解它。”
我还应该注意到,这个问题并不是一个简单的作业练习;它是针对我正在设计的个人软件项目中的网络库组件,希望能教会我有关网络、事件处理和并发性的知识。希望我能掌握我需要实现的所有其他东西……LOL
发布于 2015-04-23 23:37:35
为了给你一个小起点,这样的二进制解码器/编码器是如何看起来像这里的例子:
那么,这背后的概念是什么呢?
非常简单,我遍历您想要发送的每个数据,并将它们拆分成单个字节。举个例子:
data: 1013
bitMask: 10所以我首先计算发送它需要多少字节。在这里,这将是每字节8比特的2字节。
在所有的准备和计算之后,逐字节和逐位地发送所有数据是很简单的!因此,如果我们以上面的例子为例,它将如下所示:
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 )https://stackoverflow.com/questions/29821845
复制相似问题