El programa de descarga hexagonal más corto

13

Desafío

Cree un programa de consola para mostrar cada byte de un archivo.


Victorioso

Como se trata de , gana menos bytes.


Reglas

  • El programa debe ser una aplicación de consola , lo que significa que se ejecutará desde algún tipo de intérprete de línea de comandos;
  • Cada byte debe ser hexadecimal en mayúsculas, separado por un espacio, y debe tener 2 dígitos; (ponga el número 0 antes si tiene 1 dígito)
  • El archivo debe leerse usando IO o alternativa, y no codificado;
  • La ruta del archivo debe especificarse como un argumento de línea de comandos o un mensaje de usuario (como STDIN) ;
  • No hay escapatorias por favor ;

Ejemplo

test.txt (termina con LF)

Hello World!

$ ./hexdump.exe test.txt
48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0A
facepalm42
fuente
16
@ facepalm42 Para evitar facepalms, recomiendo utilizar Sandbox para ayudarlo a diseñar desafíos futuros antes de publicarlos.
Adám
2
¿Cómo es posible mostrar todos los valores de bytes a la vez, si no cabe en la pantalla? Desplazarse claramente no es "a la vez". Además, ¿qué tiene de malo (una función) solo devolver los valores?
Adám
77
@ facepalm42 Por favor, no cambie la especificación tanto tiempo después de publicar el desafío. La publicación original no especificó el formato exacto de los números hexadecimales, dejándolo en manos de los que respondieron. ¡Su última edición anuló mi respuesta existente!
Adám
11
¿Hay alguna razón particular por la que solo permite argumentos de línea de comandos o una solicitud de usuario? ¿Qué tiene de malo, por ejemplo, tomar el nombre del archivo como argumento de función?
Adám
3
Sería útil si tuviera un hello.txtarchivo de texto simple como ejemplo como entrada y cuál debería ser la salida esperada. Por ejemplo, si hello.txtcontuviera simplemente la palabra hellocon un salto de línea, ¿cómo se expresaría esto en la salida? ¿Está agrupando los bytes en palabras de 16 bits, 32 bits o 64 bits? ¿O cada byte se expresa como hexadecimal de dos dígitos? ¿Son aceptables los espacios después de cada byte como hexadecimal o después de cada palabra de x bits? ¿Requiere una 0xcorrección previa para cada byte?
Shaun Bebbers

Respuestas:

11

C (gcc) en * nix, 73 71 bytes

i;main(c,v)int**v;{for(c=open(v[1],0);read(c,&i,1);printf("%02X ",i));}

Pruébalo en línea! Banco de pruebas

-2 bytes gracias a Johan du Toit

Esto se basa en O_RDONLY == 0y sobre int_one == 1dónde int int_one; *(char*)&int_one = 1;.

wastl
fuente
11
69 Bytes ;)
Johan du Toit
6

Rubí , 26 bytes

$<.bytes{|b|$><<"%02X "%b}

Pruébalo en línea!

GB
fuente
¿Lee esto el contenido de un archivo dado una ruta de archivo como argumento de programa? Según el TIO, parece que acaba de leer de STDIN, pero no conozco a Ruby lo suficientemente bien como para decir que es incorrecto.
Kevin Cruijssen
1
@KevinCruijssen Sí, toma las rutas de archivo como argumento del programa. Si no hay argumentos, $<cambia a lectura de STDIN en su lugar.
Value Ink
6

Java 11, 156154 bytes

import java.nio.file.*;interface M{static void main(String[]a)throws Exception{for(int b:Files.readAllBytes(Path.of(a[0])))System.out.printf("%02X ",b);}}

-2 bytes gracias a @Holger .

Pruébelo en línea utilizando ./.input.tiocomo argumento file-path, que tendrá una entrada determinada como contenido de archivo.

Explicación:

import java.nio.file.*;        // Required import for Files and Paths
interface M{                   // Class
  static void main(String[]a)  //  Mandatory main method
      throws Exception{        //  With mandatory thrown clause for the readAllBytes builtin
                                         a[0]    // Get the first argument
                                 Path.of(    )   // Get the file using that argument as path
              Files.readAllBytes(             )  // Get all bytes from this file
    for(int b:                                 ) // Loop over each of them:
      System.out.printf(                         //  And print the current byte
                        "%02X ",b);}}            //  As uppercase hexadecimal with leading 0
                                                 //  and trailing space as delimiter
Kevin Cruijssen
fuente
¿Cuál es la razón detrás de usar en interfacelugar de class?
JakeDot
44
Se requiere que @JakeDot main sea público, los métodos de interfaz son siempre públicos, interfacees más corto que class+ public.
Grimmy
3
Con Java 11, puede usar en Path.oflugar dePaths.get
Holger
1
@ Holger ¡Gracias! :)
Kevin Cruijssen
2
@Grimy desde Java 9, los métodos de interfaz no siempre son public, pero a publicmenos que se declaren explícitamente private.
Holger
6

PHP , 60 59 54 bytes

<?=wordwrap(bin2hex(implode(file($argv[1]))),2,' ',1);
  • -1 byte gracias a manassehkatz
  • -5 bytes gracias a Blackhole

Pruébalo en línea!

John
fuente
1
Debería poder soltar el final ?>y guardar 2 bytes, o si eso no funciona, reemplácelo ?>con un punto y coma y guarde 1 byte.
manassehkatz-Moving 2 Codidact
2
Usar en implode(file($x))lugar de file_get_contents($x)(-4 bytes).
Blackhole
2
Y wordwrap(), 1como último parámetro, es un byte más corto que chunk_split().
Blackhole
5

Perl 5 ( -aF//), 23 bytes

printf"%02X ",ord for@F

TIO

Nahuel Fouilleul
fuente
4

APL (Dyalog Unicode) , 16 bytes

Función de prefijo tácito anónimo. Devuelve (e imprime implícitamente, si el valor no se consume) una matriz de dos filas con los 4 bits superiores representados como un número decimal 0-15 en la fila superior y los 4 bits inferiores representados de manera similar en la fila inferior. Es decir, la matriz tiene tantas columnas como el archivo tiene bytes.

16 1683 ¯1∘⎕MAP

Pruébalo en línea!

⎕MAP mapear el nombre de archivo del argumento a una matriz
 con parámetros:
¯1 la longitud total del archivo se
83 lee como enteros de 8 bits

16 16⊤ convertir (anti-base) a hexadecimal de 2 posiciones

Adán
fuente
1
@ facepalm42 Mucho está en hexadecimal. Por ejemplo H, 72, que es 4 × 16¹ + 8 × 16⁰ o [4,8] ₁₆. Por lo tanto, se lee la primera columna del ejemplo [4,8].
Adám
¡Oh, lo olvidé por completo! Lo siento.
facepalm42
4

Python 3, 59 bytes

-11 bytes gracias a Mayormente inofensivo!

-8 bytes gracias a James K Polk!

-24 bytes gracias a Blue!

print(' '.join('%02X'%ord(i)for i in open(input()).read()))

Pruébalo en línea!

Esto es bastante sencillo; abre un nombre de archivo dado como entrada en STDIN, lo lee, convierte cada carácter a su valor ASCII, convierte cada número a hexadecimal, quita el "0x"que precede a los valores hexademicos en Python, rellena el valor con un cero si es necesario, luego une los valores junto con espacios.

mprogrammer
fuente
Puede guardar algunos bytes en '%02X'%ord(i)lugar de cortar la salida de hexadecimal
Mayormente inofensivo
@MostlyHarmless ¡Listo! -11 bytes. ¡Gracias!
mprogrammer
¿Qué tal '% 02X' en lugar de '% 02x', y deshacerse de él.upper()
presidente James Moveon Polk
Puede guardar los bytes del import sysutilizando raw_input()como nombre de archivo en su lugar; las reglas permiten avisar al usuario.
Azul
@Blue ¡Gracias! Y es aún más corto en Python 3, donde puedes hacerinput()
mprogrammer el
3

Bash ,  33  23 bytes

... con mucha ayuda:
-3 gracias a manatwork
-4 gracias a spuck
-3 gracias a Nahuel Fouilleul

echo `xxd -c1 -p -u $1`

Pruébalo en línea!

Tenga en cuenta que el enlace TIO anterior usa entrada: podemos escribir archivos localmente, por lo que esto muestra que funciona como un programa que toma una ruta de archivo.

Jonathan Allan
fuente
Reducciones menores: xxd -u -p $1|fold -2|tr \\n \ .
manatwork
Gracias, ¿alguna idea de cómo obtener \ny \ trabajar en la versión de enlace 'this'? EDITAR: agregué otro personaje de escape.
Jonathan Allan
Si te entiendo correctamente, solo quieres cambiar de comillas dobles a comillas simples: ¡ Pruébalo en línea!
manatwork
¡Increíble gracias!
Jonathan Allan
xxd -c1 -p -u $1|tr \\n \
Spuck
3

Kotlin , 130 127 104 93 92 bytes

fun main(a:Array<String>){java.io.File(a[0]).readBytes().forEach{print("%02X ".format(it))}}

Pruébalo en línea!

Editar: -11 bytes gracias a @ChrisParton

Editar: TIO de trabajo

Editar: -1 byte gracias a @KevinCruijssen

Quinn
fuente
1
¿Podría deshacerse de la importación y la referencia Filecomo en su java.io.Filelugar?
Chris Parton
@ ChrisParton tienes razón, gracias!
Quinn
Aquí un TIO en funcionamiento. Puede usarlo ./.input.tiocomo argumento de ruta de archivo, y usará el STDIN como contenido de archivo. :)
Kevin Cruijssen
@KevinCruijssen gracias! respuesta actualizada
Quinn
1
No conozco a Kotlin, pero el TIO todavía funciona si elimino el espacio en a:Array, así que creo que puedes guardar un byte.
Kevin Cruijssen
2

Dardo , 140 134 bytes

import'dart:io';main(a){print(new File(a[0]).readAsBytesSync().map((n)=>n.toRadixString(16).toUpperCase().padLeft(2,'0')).join(' '));}

Pruébalo en línea!

-6 bytes porque olvidé reducir los nombres de las variables

Elcan
fuente
+1 para dardos. Un lenguaje tan subestimado.
vasilescur
Es difícil jugar al golf, ya que es básicamente JS sin el sistema de tipo muy laxo
Elcan el
2

Haskell, 145 143 bytes

import System.Environment
import Text.Printf
import Data.ByteString
main=getArgs>>=Data.ByteString.readFile.(!!0)>>=mapM_(printf"%02X ").unpack
Damien
fuente
1
Un poco más corto: import Data.ByteStringmás main=getArgs>>=Data.ByteString.readFile.(!!0)>>=mapM_(printf"%02X ").unpack.
nimi
2

Rust, 141 bytes (versión contribuida)

use std::{io::*,fs::*,env::*};fn main(){for x in File::open(args().nth(1).unwrap()).unwrap().bytes(){print!("{:02X} ",x.unwrap())}println!()}

Óxido, 151 bytes (versión original)

fn main(){std::io::Read::bytes(std::fs::File::open(std::env::args().nth(1).unwrap()).unwrap()).map(|x|print!("{:02X} ",x.unwrap())).count();println!()}
Vi.
fuente
-10 bytes: TIO
Herman L
2

bash + Stax, 6 + 4 + 1 = 11 bytes

Esta es la teoría completa en este punto. En realidad no puedes ejecutar esto. Si todo funciona de acuerdo con sus especificaciones, esto funcionaría, pero no todo funciona todavía.

El script bash es

]<$1

y el programa stax debe compilarse y guardarse en] es

╛↕ßú┼_

Establezca su conjunto de caracteres en ISO 8859-1 (Windows-1252 no funcionará aquí) y vaya

Desempaquetado y explicado

_          push all input as a single array
F          run the rest of the program for each element of the array
 |H        write the hex of the byte to standard output
 |         write a space to standard output
Joshua
fuente
2

Emojicode , 186 162 bytes

📦files🏠🏁🍇🔂b🍺📇🐇📄🆕🔡👂🏼❗️❗️🍇👄📫🍪🔪🔡🔢b❗️➕256 16❗️1 2❗️🔤 🔤🍪❗️❗️🍉🍉

Pruébelo en línea aquí.

Sin golf:

📦 files 🏠  💭 Import the files package into the default namespace
🏁 🍇  💭 Main code block
🔂 b  💭 For each b in ...
  🍺  💭 (ignoring IO errors)
  📇 🐇 📄  💭 ... the byte representation of the file ...
  🆕 🔡 👂🏼  💭 ... read from user input:
  ❗️ ❗️ 🍇
    👄  💭 Print ...
    📫  💭 ... in upper case (numbers in bases > 10 are in lower case) ...
    🍪  💭 ... the concatenation of:
      🔪 🔡 🔢 b ❗️ ➕ 256  💭 b + 256 (this gives the leading zero in case the hex representation of b is a single digit) ...
              16  💭 ... represented in hexadecimal ...
           ❗️
         1 2  💭 ... without the leading one,
      ❗️
      🔤 🔤  💭 ... and a space
    🍪
    ❗️❗️
  🍉
🍉
OOBalance
fuente
2

Perl 6 , 45 bytes

@*ARGS[0].IO.slurp(:bin).list.fmt('%02X').say

Pruébalo en línea!

  • @*ARGS[0] es el primer argumento de línea de comando.
  • .IOconvierte ese nombre de archivo (presunto) en un IO::Pathobjeto.
  • .slurp(:bin)lee todo el archivo en un Bufbúfer de bytes. (Sin el :bincontenido del archivo se devolvería como una cadena Unicode).
  • .list devuelve una lista de los valores de bytes del búfer.
  • .fmt('%02X')es un Listmétodo que formatea los elementos de la lista usando la cadena de formato dada, luego los une con espacios. (¡Conveniente!)
  • .say imprime esa cadena.
Sean
fuente
Basado en la respuesta de Python, un enlace TIO es de hecho bastante posible.
Draco18s ya no confía en SE
Algunos cambios pueden eliminar el .listde 41 bytes
Jo King
1

D , 98 bytes

import std;void main(string[]s){File(s[1]).byChunk(9).joiner.each!(a=>writef("%02X ",a.to!byte));}

Pruébalo en línea!

Samuel
fuente
1

Python 3, 75 bytes

Principalmente una copia de la respuesta de Maxwell en python 2.

import sys
print(' '.join('%02X'%b for b in open(sys.argv[1],'rb').read()))
Presidente James Moveon Polk
fuente
quieres decir probablemente sys.argv[1]. con sys.argv[0]este script funciona más como una quine ;-)
anion
@anion: oops, jaja, arreglando ...
Presidente James Moveon Polk
1

Raqueta, 144 bytes

Este envío genera un espacio final y no una nueva línea final. Avísame si esto se considera una escapatoria :)

(command-line #:args(f)(for([b(call-with-input-file f port->bytes)])(printf"~a "(string-upcase(~r b #:base 16 #:min-width 2 #:pad-string"0")))))

Limpiado

(command-line #:args (f)
 (for ([b (call-with-input-file f port->bytes)])
   (printf "~a "
           (string-upcase
            (~r b #:base 16 #:min-width 2 #:pad-string "0")))))
Winny
fuente
1

Adelante (gforth) , 71 bytes

: f slurp-file hex 0 do dup c@ 0 <# # # #> type space 1+ loop ;
1 arg f

Pruébalo en línea!

TIO tiene 3 argen la última línea porque TIO pasa "-e bye" al analizador de línea de comando antes de pasar el código

Explicación del código

: f             \ start a function definition
  slurp-file    \ open the file indicated by the string on top of the stack,
                \ then put its contents  in a new string on top of the stack
  hex           \ set the interpreter to base 16
  0 do          \ loop from 0 to file-length - 1 (inclusive)
    dup c@      \ get the character value from the address on top of the stack
    0 <# # # #> \ convert to a double-length number then convert to a string of length 2
    type        \ output the created string 
    space       \ output a space 
    1+          \ add 1 to the current address value
  loop          \ end the loop
;               \ end the word definition
1 arg f         \ get the filename from the first command-line argument and call the function
reffu
fuente
1

Javascript, 155 bytes

for(b=WScript,a=new ActiveXObject("Scripting.FileSystemObject").OpenTextFile(b.Arguments(0));;b.echo(('0'+a.read(1).charCodeAt(0).toString(16)).slice(-2)))
Peter Ferrie
fuente
1

VBScript, 143 bytes

set a=CreateObject("Scripting.FileSystemObject").OpenTextFile(WScript.Arguments(0)):while 1 WScript.echo(right("0"+Hex(Asc(a.read(1))),2)):wend
Peter Ferrie
fuente
1

Wolfram Language (Mathematica) , 94 89 bytes

Print@ToUpperCase@StringRiffle@IntegerString[BinaryReadList@Last@$ScriptCommandLine,16,2]

Pruébalo en línea!

El código se explica por sí mismo debido a los largos nombres de comandos. Debe leerse principalmente de derecha a izquierda:

$ScriptCommandLine       is a list of {scriptname, commandlinearg1, commandlinearg2, ...}
Last@...                 extracts the last command-line argument
BinaryReadList@...       reads the named file into a list of bytes
IntegerString[...,16,2]  converts each byte to a 2-digit hex string (lowercase)
StringRiffle@...         converts this list of strings into a single string with spaces
ToUpperCase@...          converts the string to uppercase
Print@...                prints the result to stdout
romano
fuente
1

Gema , 45 personajes

?=@fill-right{00;@radix{10;16;@char-int{?}}} 

Ejecución de muestra:

bash-5.0$ gema '?=@fill-right{00;@radix{10;16;@char-int{?}}} ' <<< 'Hello World!'
48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0A 

Pruébalo en línea!

hombre trabajando
fuente
1

Pyth , 12 bytes

jdcr1.Hjb'w2

Pruébalo en línea!

Toma datos como solicitud del usuario (no hay forma de acceder a los argumentos de la línea de comandos AFAIK)

jd           # join on spaces
  c        2 # chop into pieces of length 2
   r1        # convert to uppercase
     .H      # convert to hex string, interpreting as base 256 (*)
       jb    # join on newlines
         '   # read file as list of lines
          w  # input()

(*) No estoy 100% seguro de si esto es lo que se pretende, pero una base de 256 dígitos (como en un carácter), siempre se convertirá en exactamente 2 dígitos hexadecimales, eliminando la necesidad de rellenar con ceros.

ar4093
fuente
1

Nodo.js, 118 bytes

console.log([...require("fs").readFileSync(process.argv[2])].map(y=>(y<16?0:"")+y.toString(16).toUpperCase()).join` `)

Cómo se ve el resultado: ingrese la descripción de la imagen aquí

Por cierto, el contenido de test.txten el ejemplo es el siguiente:

做乜嘢要輸出大楷姐,搞到要加番toUpperCase()去轉番,咁就13byte啦。

(¿Por qué demonios es necesaria la salida en mayúsculas? Tuve que agregar la conversión toUpperCase()y costó 13 bytes).

Shieru Asakoto
fuente
0

C # .NET Framework 4.7.2 - 235 213 203 191 175 140 bytes

Pruébalo en línea!

using System.IO;class P{static void Main(string[]a){foreach(var b in File.ReadAllBytes(a[0])){System.Console.Write(b.ToString("X2")+" ");}}}

using System;
using System.IO;

namespace hexdump
{
    class Program
    {
        static void Main(string[] args)
        {
            // Read the bytes of the file
            byte[] bytes = File.ReadAllBytes(args[0]);

            // Loop through all the bytes and show them
            foreach (byte b in bytes)
            {
                // Show the byte converted to hexadecimal
                Console.Write(b.ToString("X2") + " ");
            }
        }
    }
}
facepalm42
fuente
1
Creo que lo siguiente ahorrará algunos bytes (ahora creo que 181): usando System.IO; clase P {Main void Main (string [] a) {if (a.Length> 0 && File.Exists (a [0]) ) {foreach (var b en File.ReadAllBytes (a [0])) {System.Console.Write ($ "{b.ToString (" X2 ")}");}}}}
PmanAce el
@PmanAce Si elimina parte del espacio en blanco, se reduce a 175.
facepalm42
0

05AB1E , 18 bytes

IvyÇh2j' 0.:' Jvy?

Pruébalo en línea!

Explicación:

IvyÇh2j' 0.:' Jvy?
Iv                 Loop through each character in input
  y                Push current character
   Ç               ASCII value
    h              Convert to hexadecimal
     2j            Pad with at least 2 spaces
       ' 0.:       Replace all spaces with 0s
            ' J    Add space to end
               vy? Convert to string and print
IvyÇh2j' 0.:' Jvy?
facepalm42
fuente