Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/254.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP包9位整数然后10位整数_Php_Binaryfiles - Fatal编程技术网

PHP包9位整数然后10位整数

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

我试图用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 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);