如何将此函数从PHP正确移植到Javascript
我正在从事一个项目,我需要一个只能从PHP项目中获得的编码:如何将此函数从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
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=>
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);
//输出: