Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

195
Views
Decodifique un VarInt antepuesto de un flujo de bytes de tamaño desconocido en javascript/Nodejs

Estoy escribiendo una pequeña biblioteca de utilidades para solicitar el estado del servidor de un host de Minecraft dado en js en el nodo. Estoy usando el Protocolo de ping de la lista de servidores como se describe aquí ( https://wiki.vg/Server_List_Ping ) y lo hice funcionar en su mayoría como se esperaba, aunque tuve grandes problemas para trabajar con tipos de datos no compatibles ( VarInt ) y tuve que buscar en Internet para encontrar una forma de convertir js nums en VarInts para crear los búferes de paquetes necesarios:

 function toVarIntBuffer(integer) { let buffer = Buffer.alloc(0); while (true) { let tmp = integer & 0b01111111; integer >>>= 7; if (integer != 0) { tmp |= 0b10000000; } buffer = Buffer.concat([buffer, Buffer.from([tmp])]); if (integer <= 0) break; } return buffer; }

En este momento, puedo solicitar un estado del servidor enviando el paquete de protocolo de enlace y luego el paquete de consulta y recibo una respuesta JSON con la longitud de la respuesta antepuesta como VarInt.

Sin embargo, el problema está aquí , donde simplemente no sé cómo identificar de forma segura el VarInt desde el comienzo de la respuesta JSON (ya que puede estar en cualquier lugar hasta 5 bytes) y decodificarlo de nuevo a un num para poder obtener el longitud adecuada del flujo de bytes de respuesta.

[...] con todas las cadenas, esto tiene el prefijo de su longitud como VarInt

(de la documentación del protocolo)

Mi solución super hacky actual es concatenar los fragmentos como String hasta que la cadena concatenada contenga el mismo recuento de '{'s y '}'s (es decir, un objeto json completo) y dividir la respuesta json en el primer '{' antes de analizar eso.

Sin embargo, estoy muy descontento con esta forma ineficaz, ineficiente, poco elegante y posiblemente poco confiable de resolver el problema y preferiría decodificar el VarInt frente a la respuesta JSON para obtener una longitud adecuada para comparar.

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

No conozco este protocolo, pero VarInt en protobuf está codificado con el bit MSB:

Cada byte en una variante, excepto el último byte, tiene establecido el bit más significativo (msb), lo que indica que hay más bytes por venir. Los 7 bits inferiores de cada byte se utilizan para almacenar la representación del número en complemento a dos en grupos de 7 bits, el grupo menos significativo primero.

Nota: Demasiado largo para un comentario, por lo que se publica como respuesta.

Actualización: navegué un poco a través de la URL que proporcionó, y de hecho es ProtoBuf VarInt. También se describe allí con pseudocódigo:

https://wiki.vg/Protocol#VarInt_and_VarLong

VarInt y VarLong Formato de longitud variable tal que los números más pequeños usan menos bytes. Son muy similares a las variantes de búfer de protocolo: los 7 bits menos significativos se utilizan para codificar el valor y el bit más significativo indica si hay otro byte después de él para la siguiente parte del número. El grupo menos significativo se escribe primero, seguido de cada uno de los grupos más significativos; por lo tanto, VarInts son efectivamente little endian (sin embargo, los grupos son de 7 bits, no de 8).

VarInts nunca superan los 5 bytes y VarLongs nunca superan los 10 bytes.

Pseudocódigo para leer y escribir VarInts y VarLongs:

about 4 years ago · Juan Pablo Isaza Report

0

Gracias al material de referencia que @thst me señaló, pude juntar una forma funcional de leer VarInts en javascript.

 function readVarInt(buffer) { let value = 0; let length = 0; let currentByte; while (true) { currentByte = buffer[length]; value |= (currentByte & 0x7F) << (length * 7); length += 1; if (length > 5) { throw new Error('VarInt exceeds allowed bounds.'); } if ((currentByte & 0x80) != 0x80) break; } return value; }

buffer debe ser un flujo de bytes que comience con VarInt, idealmente usando la clase std Buffer .

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!