PHP包9位整数然后10位整数
我试图用PHP编写一个程序,它获取9位整数(0-511)和10位整数(0-1023)的列表,并将它们作为二进制文件写入文件,然后将其读回。例如:PHP包9位整数然后10位整数,php,binaryfiles,Php,Binaryfiles,我试图用PHP编写一个程序,它获取9位整数(0-511)和10位整数(0-1023)的列表,并将它们作为二进制文件写入文件,然后将其读回。例如: $dataIn = array(array(275, 863), array(7, 93), array(510, 1010)); $binData = writeBin($dataIn); $dataOut = readBin($binData); var_dump($dataIn, $dataOut, $binData); function
$dataIn = array(array(275, 863), array(7, 93), array(510, 1010));
$binData = writeBin($dataIn);
$dataOut = readBin($binData);
var_dump($dataIn, $dataOut, $binData);
function writeBin($data) {
$bin = "";
foreach ($data as $d) {
// 9 bit 10 bit
$bin .= pack('SS', $d[0], $d[1]);
}
return $bin;
}
function readBin($bin) {
$bin = str_split($bin, 4);
$data = array();
foreach ($bin as $b) {
$up = unpack('SS', $b); // im only getting 275, 7 and 510 here
$data[] = $up;
}
return $data;
}
但是我怎样才能将它们写入二进制文件/字符串,使每个部分都有19位的长度,然后在读回时将其拆分为19位呢?因此,一个包含10条记录的文件应该只有190位我通过编写自己的类来将不同的位长数字写入二进制文件,从而解决了这个问题:
$listLen = 10;
// get an array of 10 random 9 bit ints
$b9s = range(0, 511);
shuffle($b9s);
$b9s = array_slice($b9s, 0, $listLen);
// get an array of 10 random 10 bit ints
$b10s = range(0, 1023);
shuffle($b10s);
$b10s = array_slice($b10s, 0, $listLen);
//build array of input data
$dataIn = array();
for ($i = 0; $i < $listLen; $i++) {
$dataIn[] = array($b9s[$i], $b10s[$i]);
}
//-------
//initialise
$bitFormat = array(9, 10);
$BC = new BinConverter($bitFormat);
//pack
$BC->addData($dataIn);
$binData = $BC->getBin();
//unpack
$BC->setBin($binData);
$dataOut = $BC->getData();
var_dump($dataOut, $binData);
Class BinConverter {
private $bitFormat;
private $maxSectLen;
private $binary;
private $binData;
private $dataOffset;
// $bitFormat = list of bit lengths e.g. array(9, 10)
public function __construct($bitFormat) {
$this->setBitFormat($bitFormat);
$this->binary = "";
$this->binData = "";
$this->dataOffset = 0;
}
// $bitFormat = list of bit lengths e.g. array(9, 10)
public function setBitFormat($bitFormat) {
$bitFormat = array_merge($bitFormat);
$this->bitFormat = $bitFormat;
$this->maxSectLen = 0;
foreach ($this->bitFormat as $bpos => $bf) {
$this->bitFormat[$bpos] = (int) $bf;
$this->maxSectLen += $this->bitFormat[$bpos];
}
}
// $data = list of data sections to convert e.g. array(array(167, 89), array(62, 32), array(325, 975))
public function addData($data) {
foreach ($data as $d) {
$d = array_merge($d);
if (is_array($d) && count($d) != count($this->bitFormat)) {
throw new Exception("Invalid data section");
}
foreach ($d as $dpos => $dbit) {
$dbit = (int) $dbit;
$tbin = decbin($dbit);
if (strlen($tbin) > $this->bitFormat[$dpos]) {
throw new Exception("Data (".$dbit.") too big for ".$this->bitFormat[$dpos]." bit segment");
}
$this->binary .= $this->binPad($tbin, $this->bitFormat[$dpos]);
}
}
}
//returns binary representation of added data
public function getBin() {
$bin = "";
if ($this->binary) {
$bits = str_split($this->binary, 4);
foreach ($bits as $bpos => $bit) {
$bp = bindec($this->binPad($bit, 4));
$bin .= pack('C', $bp);
}
}
return $bin;
}
//$bin = string of binary data
public function setBin($bin) {
if (!is_string($bin)) {
throw new Exception("Invalid binary format");
}
$bdata = "";
foreach (str_split($bin) as $b) {
$unpacked = unpack('C', $b);
$binbit = $this->binPad(decbin($unpacked[1]), 4);
$bdata .= $binbit;
}
$this->binData = $bdata;
}
//returns unpacked data in the current bit format
public function getData() {
$data = array();
$binlen = strlen($this->binData);
if ($binlen) {
$bdata = $this->binData;
$overflow = $binlen % $this->maxSectLen % 4;
$lastbit = substr($bdata, -4);
$overflowBit = substr($lastbit, 0, $overflow);
$binbit = substr($lastbit, $overflow);
$bdata = substr($bdata, 0, -4) . $binbit;
$tdata = str_split($bdata, $this->maxSectLen);
foreach ($tdata as $d) {
if (strlen($d) != $this->maxSectLen) {
throw new Exception("Invalid binary format");
}
$offset = 0;
$ds = array();
foreach ($this->bitFormat as $bf) {
$ds[] = bindec(substr($d, $offset, $bf));
$offset += $bf;
}
$data[] = $ds;
}
}
return $data;
}
//returns unpacked data in the current bit format for (int) $ni number of sections
public function getNextSection($ni = null) {
$data = array();
$binlen = strlen($this->binData);
if ($binlen) {
$n = $ni;
if ($n === null) {
$n = 1;
}
$glen = $n*$this->maxSectLen;
$bdata = substr($this->binData, $this->dataOffset, $glen);
if (strlen($bdata) != $glen) {
throw new Exception("Invalid data format used");
}
$this->dataOffset += $glen;
if ($this->dataOffset+4 > $binlen) {
$overflow = $binlen - $this->dataOffset;
$lastbit = substr($this->binData, -4);
$overflowBit = substr($lastbit, 0, $overflow);
$binbit = substr($lastbit, $overflow);
$bdata = substr($bdata, 0, -(4-$overflow)) . $binbit;
}
$tdata = str_split($bdata, $this->maxSectLen);
foreach ($tdata as $d) {
if (strlen($d) != $this->maxSectLen) {
throw new Exception("Invalid binary format");
}
$offset = 0;
$ds = array();
foreach ($this->bitFormat as $bf) {
$ds[] = bindec(substr($d, $offset, $bf));
$offset += $bf;
}
$data[] = $ds;
}
if ($ni === null) {
return $data[0];
}
}
return $data;
}
private function binPad($var, $a) {
return str_pad($var, $a, '0', STR_PAD_LEFT);
}
}
$listLen=10;
//获取10个随机9位整数的数组
$b9s=范围(0511);
洗牌(B9美元);
$b9s=数组\ U片($b9s,0,$listLen);
//获取10个随机10位整数的数组
$b10s=范围(01023);
洗牌(10美元);
$b10s=数组\ U片($b10s,0,$listLen);
//构建输入数据数组
$dataIn=array();
对于($i=0;$i<$listLen;$i++){
$dataIn[]=array($b9s[$i],$b10s[$i]);
}
//-------
//初始化
$bitFormat=数组(9,10);
$BC=新的二进制转换器($bitFormat);
//打包
$BC->addData($dataIn);
$binData=$BC->getBin();
//打开
$BC->setBin($binData);
$dataOut=$BC->getData();
变量转储($dataOut,$binData);
类二进制转换器{
私人$比特格式;
私人$maxSectLen;
私人$binary;
私人$binData;
私人$dataOffset;
//$bitFormat=位长度列表,例如数组(9,10)
公共函数构造($bitFormat){
$this->setBitFormat($bitFormat);
$this->binary=“”;
$this->binData=“”;
$this->dataOffset=0;
}
//$bitFormat=位长度列表,例如数组(9,10)
公共函数setBitFormat($bitFormat){
$bitFormat=array\u merge($bitFormat);
$this->bitFormat=$bitFormat;
$this->maxSectLen=0;
foreach($bpos=>$bf形式的此->位格式){
$this->bitFormat[$bpos]=(int)$bf;
$this->maxSectLen+=$this->bitFormat[$bpos];
}
}
//$data=要转换的数据段列表,例如数组(数组(167,89)、数组(62,32)、数组(325,975))
公共函数addData($data){
foreach($d数据){
$d=数组合并($d);
if(is_数组($d)&&count($d)!=count($this->bitFormat)){
抛出新异常(“无效数据段”);
}
foreach($d作为$dpos=>$dbit){
$dbit=(int)$dbit;
$tbin=decbin($dbit);
if(strlen($tbin)>$this->bitFormat[$dpos]){
抛出新异常(“数据(“.dbit.”)对于“$this->bitFormat[$dpos]”位段而言太大;
}
$this->binary.=$this->binPad($tbin,$this->bitFormat[$dpos]);
}
}
}
//返回添加数据的二进制表示形式
公共函数getBin(){
$bin=“”;
如果($this->binary){
$bits=str_split($this->binary,4);
foreach($bpos=>$bit的位){
$bp=bindec($this->binPad($bit,4));
$bin.=包装($C',$bp);
}
}
返回$bin;
}
//$bin=二进制数据字符串
公共职能受挫($bin){
如果(!是字符串($bin)){
抛出新异常(“无效二进制格式”);
}
$bdata=“”;
foreach(str_分割($bin)为$b){
$unpacket=unpacket($C',$b);
$binbit=$this->binPad(decbin($unpacket[1]),4);
$bdata.=$binbit;
}
$this->binData=$bdata;
}
//以当前位格式返回未打包的数据
公共函数getData(){
$data=array();
$binlen=strlen($this->binData);
如果($binlen){
$bdata=$this->binData;
$overflow=$binlen%$this->maxSectLen%4;
$lastbit=substr($bdata,-4);
$overflowBit=substr($lastbit,0,$overflow);
$binbit=substr($lastbit,$overflow);
$bdata=substr($bdata,0,-4)。$binbit;
$tdata=str\u split($bdata,$this->maxSectLen);
foreach($t数据为$d){
如果(strlen($d)!=$this->maxSectLen){
抛出新异常(“无效二进制格式”);
}
$offset=0;
$ds=array();
foreach($this->bit格式为$bf){
$ds[]=bindec(substr($d,$offset,$bf));
$offset+=$bf;
}
$data[]=$ds;
}
}
返回$data;
}
//以当前位格式返回(int)$ni节数的未打包数据
公共函数getNextSection($ni=null){
$data=array();
$binlen=strlen($this->binData);
如果($binlen){
$n=$ni;
如果($n==null){
$n=1;
}
$glen=$n*$this->maxSectLen;
$bdata=substr($this->binData,$this->dataOffset,$glen);
如果(strlen($bdata)!=格伦){
抛出新异常(“使用的数据格式无效”);
}
$this->dataOffset+=$glen;
如果($this->dataOffset+4>$binlen){
$overflow=$binlen-$this->dataOffset;
$lastbit=substr($this->binData,-4);
$overflowBit=substr($lastbit,0,$overflow);
$binbit=substr($lastbit,$overflow);
$bdata=substr($bdata,0,-(4-$overflow))。$binbit;
}
$tdata=str\u split($bdata,$this->maxSectLen);
foreach($t数据为$d){
如果(strlen($d)!=$this->maxSectLen){
抛出新异常(“无效二进制格式”);
}
$offset=0;
$ds=array();
foreach($this->bit格式为$bf){
$ds[]=bindec(substr($d,$offset,$bf));
$offset+=$bf;
}
$data[]=$ds;
}
如果($
$listLen1 = rand(1, 20);
// get an array of 10 random 9 bit ints
$b9s = range(0, 511);
shuffle($b9s);
$b9s = array_slice($b9s, 0, $listLen1);
// get an array of 10 random 10 bit ints
$b10s = range(0, 1023);
shuffle($b10s);
$b10s = array_slice($b10s, 0, $listLen1);
//build array of input data
$dataIn1 = array();
for ($i = 0; $i < $listLen1; $i++) {
$dataIn1[] = array($b9s[$i], $b10s[$i]);
}
$listLen2 = rand(1, 20);
// get an array of 10 random 16 bit ints
$b16s = range(0, 65535);
shuffle($b16s);
$b16s = array_slice($b16s, 0, $listLen2);
// get an array of 10 random 8 bit ints
$b8s = range(0, 255);
shuffle($b8s);
$b8s = array_slice($b8s, 0, $listLen2);
// get an array of 10 random 14 bit ints
$b14s = range(0, 16383);
shuffle($b14s);
$b14s = array_slice($b14s, 0, $listLen2);
$dataIn2 = array();
for ($i = 0; $i < $listLen2; $i++) {
$dataIn2[] = array($b16s[$i], $b8s[$i], $b14s[$i]);
}
//-------
$file = './binfile.bf';
//initialise
$bitFormat1 = array(9, 10);
$bitFormat2 = array(16, 8, 14);
$BC = new BinConvert($bitFormat1);
//pack
$BC->addData($dataIn1);
$BC->setBitFormat($bitFormat2);
$BC->addData($dataIn2);
$binData = $BC->getBin();
file_put_contents($file,$binData);
//unpack
$binData = file_get_contents($file);
$BC->setBin($binData);
$BC->setBitFormat($bitFormat1);
$dataOut1 = $BC->getNextSection($listLen1);
$BC->setBitFormat($bitFormat2);
$dataOut2 = $BC->getNextSection($listLen2);
var_dump($dataOut1, $dataOut2, $binData);