Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.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正确移植到Javascript_Javascript_Php_Binary Data - Fatal编程技术网

如何将此函数从PHP正确移植到Javascript

如何将此函数从PHP正确移植到Javascript,javascript,php,binary-data,Javascript,Php,Binary Data,我正在从事一个项目,我需要一个只能从PHP项目中获得的编码: public static function writeVarLong(int $v) : string{ return self::writeUnsignedVarLong(($v << 1) ^ ($v >> 63)); } public static function writeUnsignedVarLong(int $value) : string{ $buf = "&quo

我正在从事一个项目,我需要一个只能从PHP项目中获得的编码:

public static function writeVarLong(int $v) : string{
    return self::writeUnsignedVarLong(($v << 1) ^ ($v >> 63));
}

public static function writeUnsignedVarLong(int $value) : string{
    $buf = "";
    for($i = 0; $i < 10; ++$i){
        if(($value >> 7) !== 0){
            $buf .= chr($value | 0x80); //Let chr() take the last byte of this, it's faster than adding another & 0x7f.
        }else{
            $buf .= chr($value & 0x7f);
            return $buf;
        }

        $value = (($value >> 7) & (PHP_INT_MAX >> 6)); //PHP really needs a logical right-shift operator
    }

    throw new InvalidArgumentException("Value too large to be encoded as a VarLong");
}
以下是Javascript测试和输出:

$stream = new NetworkBinaryStream();
$stream->putVarLong(422212465606656);
var_dump(bin2hex($stream->buffer));
// Output: 8080c2808080c001
let stream = new PacketBinaryStream()
stream.writeVarLong(422212465606656)
console.log(stream.buffer)
// Output: 80 80 42
正如我们所看到的,输出是不同的

完整文件:

  • PHP=>

  • Javascript=>


这些方法遇到了一个问题,即按位运算符仅在32位中工作,因此在序列化之前会截断64位数字

你可以用BigInt解决这个问题

const BinaryStream = require('jsbinaryutils')

class PacketBinaryStream extends BinaryStream {
    writeVarLong(v) {
        let bi = BigInt(v);
        return this.writeUnsignedVarLong((bi << 1n) ^ (bi >> 63n))
    }

    writeUnsignedVarLong(v) {
        let bi = BigInt(v);
        for (let i = 0; i < 10; i++) {
            if ((bi >> 7n) !== 0n) {
                this.writeByte(Number((bi | 0x80n)));
            } else {
                this.writeByte(Number((bi & 0x7fn)));
                break
            }
            bi >>= 7n
        }
    }
}

let toWrite = 422212465606656;
let stream = new PacketBinaryStream();
stream.writeVarLong(toWrite);
console.log(stream.buffer);

// Output: <Buffer 80 80 c2 80 80 80 c0 01>
const BinaryStream=require('jsbinarytils')
类PacketBinaryStream扩展了BinaryStream{
写长(v){
设bi=BigInt(v);
返回此.writeUnsignedVarLong((bi>63n))
}
书面签名(五){
设bi=BigInt(v);
for(设i=0;i<10;i++){
如果((bi>>7n)!==0n){
这个.writeByte(数字((bi | 0x80n));
}否则{
这个.writeByte(数字((bi&0x7fn));
打破
}
bi>>=7n
}
}
}
让toWrite=42221246565656;
let stream=new PacketBinaryStream();
stream.writeVarLong(toWrite);
console.log(stream.buffer);
//输出:

这些方法遇到了一个问题,即按位运算符仅在32位中工作,因此在序列化之前会截断64位数字

你可以用BigInt解决这个问题

const BinaryStream = require('jsbinaryutils')

class PacketBinaryStream extends BinaryStream {
    writeVarLong(v) {
        let bi = BigInt(v);
        return this.writeUnsignedVarLong((bi << 1n) ^ (bi >> 63n))
    }

    writeUnsignedVarLong(v) {
        let bi = BigInt(v);
        for (let i = 0; i < 10; i++) {
            if ((bi >> 7n) !== 0n) {
                this.writeByte(Number((bi | 0x80n)));
            } else {
                this.writeByte(Number((bi & 0x7fn)));
                break
            }
            bi >>= 7n
        }
    }
}

let toWrite = 422212465606656;
let stream = new PacketBinaryStream();
stream.writeVarLong(toWrite);
console.log(stream.buffer);

// Output: <Buffer 80 80 c2 80 80 80 c0 01>
const BinaryStream=require('jsbinarytils')
类PacketBinaryStream扩展了BinaryStream{
写长(v){
设bi=BigInt(v);
返回此.writeUnsignedVarLong((bi>63n))
}
书面签名(五){
设bi=BigInt(v);
for(设i=0;i<10;i++){
如果((bi>>7n)!==0n){
这个.writeByte(数字((bi | 0x80n));
}否则{
这个.writeByte(数字((bi&0x7fn));
打破
}
bi>>=7n
}
}
}
让toWrite=42221246565656;
let stream=new PacketBinaryStream();
stream.writeVarLong(toWrite);
console.log(stream.buffer);
//输出: