Resumen

  • El NVT creó una forma intermedia: CR LF era la función de línea nueva y CR NUL un retorno de carro sin avance vertical; un CR desnudo no era válido en el modo ASCII inicial.
  • El octeto posterior a CR permitía decidir localmente sin conocer el terminal del otro extremo, mientras cada host conservaba la traducción hacia sus propias teclas y controladores.
  • La RFC 1123 distinguió la tecla Enter del formato de salida, el modo Binary desactivó la conversión de fin de línea y Net-Unicode heredó CRLF reduciendo el papel de CR NUL.

Una tecla no define por sí sola el mensaje

Un usuario pulsa Enter. El cliente puede verlo como “terminar el comando”, como el carácter CR de un teclado ASCII o como una señal que debe entregar sin formato a un editor remoto. El servidor, a su vez, puede usar CR, LF, ambos o una estructura interna diferente para cerrar una línea.

Telnet no resolvió esa diversidad proclamando una tecla universal. Construyó una máquina intermedia. En el Network Virtual Terminal, CR llevaba el carro al margen izquierdo de la misma línea; LF bajaba una línea y mantenía la columna. La combinación CR LF realizaba la función completa de línea nueva.

El receptor tenía que saber si un CR anunciaba esa pareja o si debía actuar solo. La RFC 318 propuso en 1972 retenerlo hasta ver el carácter siguiente. LF cerraba la decisión como línea nueva. NUL, que no movía la impresora virtual, cerraba la decisión como retorno de carro solamente.

Por eso CR NUL no era una secuencia vacía. El segundo octeto decía que la ausencia de LF era intencional.

La capa común describía acciones, no máquinas

La RFC 854 convirtió el NVT en el estado inicial de una conexión Telnet. Ningún extremo necesitaba aprender cada detalle del teclado o del sistema operativo remoto. Ambos traducían hacia una representación compartida y desde ella.

La norma hizo obligatoria la gramática. Cuando se buscaba la acción combinada debía enviarse CR LF y tratarse como una sola línea nueva. Para un retorno de carro aislado debía usarse CR NUL. En el modo NVT ASCII por defecto, CR no podía aparecer en otros contextos. La obligación era simétrica para ambos sentidos.

Al recibir CR NUL, Telnet retiraba NUL antes de transformar la acción a la codificación local. Ese byte pertenecía al encuadre semántico de NVT. Entregarlo siempre a la aplicación sería tan incorrecto como borrarlo siempre de cualquier flujo.

La frontera era estrecha: el protocolo acordaba qué acción representaba cada pareja; el host decidía cómo realizarla. No convertía CRLF en el formato de almacenamiento obligatorio del mundo.

La ambigüedad reapareció en la entrada humana

La descripción de la impresora no contestaba completamente qué debía enviar el cliente cuando el usuario pulsaba su tecla de fin de línea. La RFC 1123 reconoció que algunas implementaciones elegían CR LF y otras CR NUL. No era una diferencia puramente estética: los hosts no ASCII podían perder el retorno de carro literal o dejar de interoperar.

La reparación distribuyó obligaciones. Un User Telnet debía poder producir CR LF, CR NUL y LF. En un host ASCII debía ofrecer, de preferencia, un modo controlable para elegir entre las dos primeras formas y usar CR LF como opción inicial para Enter. Un servidor ASCII tenía que dar a CR LF y CR NUL el mismo efecto que su tecla local de fin de línea cuando eran entrada de terminal.

El contexto seguía importando. En modo crudo, un pseudoterminal podía entregar CR a la aplicación; en modo formateado, aplicaba la convención local. Para salida del servidor o texto de otro protocolo transportado mediante Telnet, el fin de línea debía ser CR LF.

La misma persona podía ver un solo botón, pero el protocolo veía dirección, función y modo. Esa información evitaba que la interfaz humana usurpara la semántica del flujo.

Binary retiraba la autoridad al formateador

La opción Binary de la RFC 856 se negociaba por dirección. Sólo existía cuando una parte la proponía y la otra la aceptaba. Los octetos ordinarios se interpretaban como datos de ocho bits, aunque IAC seguía introduciendo órdenes Telnet y debía duplicarse para representar el valor 255 como dato.

La RFC 1123 fue tajante: en Binary no hay convención de fin de línea. No se puede sustituir CR por CR NUL ni por CR LF. Activar el modo cambia el intérprete competente; no se limita a ampliar el alfabeto de NVT.

Un filtro que quite NUL después de CR sin leer la negociación puede reparar una sesión de texto y dañar una sesión binaria. Un filtro que inserte NUL hace el daño inverso. La validez depende de estado y sentido, no sólo de reconocer dos números consecutivos.

Linemode asignó la edición al borde cercano

La RFC 1184 permitió editar una línea en el cliente para no pagar un viaje de red por cada carácter. Con la edición activada, un terminador local normal viajaba como CR LF. Sin edición, un retorno de carro viajaba como CR NUL; LF seguía siendo LF; una tecla especial que significara “línea terminada” se convertía en CR LF.

La salida continuaba bajo responsabilidad del servidor: CR LF para una nueva línea, CR NUL para volver al margen sin bajar y LF para bajar sin volver al margen. Mover el lugar donde se edita no daba al cliente autoridad sobre el significado de la salida remota.

Así, Telnet separó una optimización de latencia de una decisión semántica. El rendimiento podía localizarse; el contrato de representación seguía siendo común.

CRLF sobrevivió a la impresora imaginaria

La RFC 5198 llevó la historia a Net-Unicode. Escogió UTF-8 y mantuvo CRLF como fin de línea. También conservó la regla estructural de que CR debe ir seguido de LF o NUL, pero recomendó evitar CR NUL: los efectos de sobreimpresión perdieron utilidad y NUL podía cortar cadenas en software moderno.

No fue una negación del problema original. El entorno había cambiado. La pareja destinada a líneas quedó profundamente instalada; el retorno de carro aislado dejó de justificar el mismo peso.

El registro de opciones Telnet de IANA conserva Binary, Linemode y las opciones de disposición. Es prueba de nombres y códigos, no de adopción actual ni de calidad de implementación.

El límite que se pierde al normalizar demasiado pronto

La arquitectura funcionaba porque cada decisión tenía dueño. El cliente convertía una intención local en una acción NVT. El byte posterior a CR hacía verificable esa acción. El servidor la convertía a su mundo local. La negociación podía entregar el flujo a otro intérprete.

Los fallos aparecen cuando una capa actúa antes de tener autoridad: una biblioteca trata NUL como fin de cadena, una pasarela unifica todos los retornos o una captura guarda sólo el texto visible. Después, ninguna discusión puede reconstruir el byte que se descartó.

Fuentes y límites de la evidencia

Las fuentes establecen las reglas, aclaraciones y excepciones negociadas. No miden el uso presente, no certifican productos y no demuestran que todas las implementaciones históricas coincidieran. Este análisis limita CR NUL al contrato donde sus octetos y su estado le daban significado.