Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

200
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda