Programma di dumping esadecimale più breve


13

Sfida

Creare un programma console per visualizzare ogni byte di un file.


vincente

Dato che si tratta di , vince il minor numero di byte.


Regole

  • Il programma deve essere un'applicazione console , il che significa che verrà eseguito da una sorta di interprete da riga di comando;
  • Ogni byte deve essere in maiuscolo esadecimale, separato da uno spazio e deve contenere 2 cifre; (metti il ​​numero 0 prima se ha 1 cifra)
  • Il file deve essere letto usando IO o in alternativa e non deve essere codificato;
  • Il percorso del file deve essere specificato come argomento della riga di comando o come prompt dell'utente (come STDIN) ;
  • Nessuna scappatoia per favore ;

Esempio

test.txt (termina con LF)

Hello World!

$ ./hexdump.exe test.txt
48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0A

16
@ facepalm42 Per evitare i facepal, ti consiglio vivamente di utilizzare Sandbox per aiutarti a progettare sfide future prima di pubblicarle.
Adám,

2
Come è possibile visualizzare tutti i valori di byte contemporaneamente, se non si adatta allo schermo? Lo scorrimento chiaramente non è "in una volta". Inoltre, cosa c'è di sbagliato in (una funzione) solo restituendo i valori?
Adám,

7
@ facepalm42 Non modificare le specifiche così a lungo dopo aver pubblicato la sfida. Il post originale non specificava il formato esatto dei numeri esadecimali, lasciandolo ai rispondenti. L'ultima modifica ha invalidato la mia risposta esistente!
Adám,

11
C'è un motivo particolare per cui consenti solo l'argomento della riga di comando o un prompt utente? Cosa c'è che non va nel prendere il nome del file come argomento di funzione?
Adám,

3
Sarebbe utile se tu avessi un semplice hello.txtfile di testo come esempio come input e quale dovrebbe essere l'output previsto. Ad esempio, se hello.txtcontenesse semplicemente la parola hellocon un'interruzione di riga, come verrebbe espressa in output? Stai raggruppando i byte in parole a 16, 32 o 64 bit? O ogni byte è espresso come esadecimale a due cifre? Gli spazi sono accettabili dopo ogni byte come esadecimali o dopo ogni parola x-bit? È necessaria una 0xpre-correzione per ogni byte?
Shaun Bebbers,

Risposte:



6

Rubino , 26 byte

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

Provalo online!


Questo legge il contenuto di un file dato un percorso di file come argomento del programma? Sulla base del TIO sembra appena letto da STDIN, ma non conosco Ruby abbastanza bene da dire che non è corretto.
Kevin Cruijssen,

1
@KevinCruijssen Sì, accetta i percorsi di file come argomento del programma. Se non ci sono argomenti, $<passa invece alla lettura da STDIN.
Valore inchiostro


6

Java 11, 156 154 byte

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 byte grazie a @Holger .

Provalo online usando ./.input.tiocome argomento percorso-file, che avrà un dato input come contenuto-file.

Spiegazione:

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

Qual è la logica dietro l'utilizzo interfaceinvece di class?
Jake,

4
@JakeDot main deve essere pubblico, i metodi di interfaccia sono sempre pubblici, interfaceè più breve di class+ public.
Grimmy,

3
Con Java 11, è possibile utilizzare Path.ofanzichéPaths.get
Holger il

1
@Holger Grazie! :)
Kevin Cruijssen,

2
@Grimy da Java 9, i metodi di interfaccia non sono sempre public, ma sono publicse non esplicitamente dichiarati private.
Holger,

6

PHP , 60 59 54 byte

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

Provalo online!


1
Dovrebbe essere in grado di eliminare il trailing ?>e salvare 2 byte, o se non funziona, sostituirlo ?>con un punto e virgola e salvare 1 byte.
manassehkatz-Moving 2 Codidact,

2
Utilizzare implode(file($x))invece di file_get_contents($x)(-4 byte).
Blackhole,

2
E wordwrap(), con 1l'ultimo parametro, è un byte più corto di chunk_split().
Blackhole,


4

APL (Dyalog Unicode) , 16 byte

Funzione prefisso tacito anonimo. Restituisce (e stampa implicitamente, se il valore non viene altrimenti consumato) una matrice a due righe con i primi 4 bit rappresentati come un numero decimale 0–15 nella riga superiore e i 4 bit inferiori rappresentati in modo simile nella riga inferiore. Cioè, la matrice ha tante colonne quanti sono i byte nel file.

16 1683 ¯1∘⎕MAP

Provalo online!

⎕MAP associa il nome file dell'argomento a un array
 con parametri:
¯1 l'intera lunghezza del file viene
83 letta come numeri interi a 8 bit

16 16⊤ convertire (anti-base) in esadecimale a 2 posizioni


1
@ facepalm42 È molto in esadecimale. Ad esempio Hè 72, che è 4 × 16¹ + 8 × 16⁰ o [4,8] ₁₆. Quindi la prima colonna nell'esempio recita [4,8].
Adám,

Oh, mi ero completamente dimenticato! Scusa.
facepalm42,

4

Python 3, 59 byte

-11 byte grazie a Mostly Harmless!

-8 byte grazie a James K Polk!

-24 byte grazie a Blue!

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

Provalo online!

Questo è piuttosto semplice; apre un nome file dato come input su STDIN, lo legge, converte ogni carattere nel suo valore ASCII, converte ogni numero in esadecimale, toglie il valore "0x"che precede i valori esadecimali in Python, riempie il valore con uno zero se necessario, quindi unisce i valori insieme agli spazi.


Può salvare qualche byte con '%02X'%ord(i)invece di tagliare l'output di hex
Mostly Harmless

@MostlyHarmless Done! -11 byte. Grazie!
mprogrammer,

che ne dici di "% 02X" invece di "% 02x" e di sbarazzartene.upper()
Presidente James Moveon Polk,

È possibile salvare i byte import sysda usando invece raw_input()come nome file; le regole consentono la richiesta dell'utente.
Blue

@Blue Grazie! Ed è ancora più breve in Python 3, dove puoi semplicemente farloinput()
mprogrammer

3

Bash ,  33  23 byte

... con molto aiuto:
-3 grazie all'opera manuale
-4 grazie allo spuck
-3 grazie a Nahuel Fouilleul

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

Provalo online!

Nota che il link TIO sopra usa l'input: possiamo scrivere file localmente, quindi questo mostra che funziona come un programma che prende un percorso di file.


Riduzioni minori: xxd -u -p $1|fold -2|tr \\n \ .
arte

Grazie, hai idea di come ottenere \ne \ come lavorare nella versione di questo link? EDIT: ho aggiunto un altro personaggio di escape.
Jonathan Allan,

Se ti capisco correttamente, vuoi solo passare da virgolette doppie a virgolette singole: provalo online!
arte

Fantastico grazie!
Jonathan Allan,

xxd -c1 -p -u $1|tr \\n \
Sparato il

3

Kotlin , 130 127 104 93 92 byte

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

Provalo online!

Modifica: -11 byte grazie a @ChrisParton

Modifica: TIO funzionante

Modifica: -1 byte grazie a @KevinCruijssen


1
Potresti abbandonare l'importazione e il riferimento Filecome java.io.Fileinvece?
Chris Parton,

@ChrisParton hai ragione, grazie!
Quinn,

Qui un TIO funzionante. È possibile utilizzare ./.input.tiocome argomento del percorso del file e utilizzerà STDIN come contenuto del file. :)
Kevin Cruijssen il

@KevinCruijssen grazie! risposta appena aggiornata
Quinn,

1
Non conosco Kotlin, ma il TIO funziona ancora se rimuovo lo spazio in a:Array, quindi penso che puoi salvare un byte.
Kevin Cruijssen,

2

Dardo , 140 134 byte

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

Provalo online!

-6 byte perché ho dimenticato di ridurre i nomi delle variabili


+1 per il dardo. Un linguaggio così sottovalutato.
vasilescur,

Difficile giocare a golf, dal momento che è fondamentalmente JS senza il sistema di tipo molto rilassato
Elcan

2

Haskell, 145 143 byte

import System.Environment
import Text.Printf
import Data.ByteString
main=getArgs>>=Data.ByteString.readFile.(!!0)>>=mapM_(printf"%02X ").unpack

1
Un po 'più breve: in import Data.ByteStringpiù main=getArgs>>=Data.ByteString.readFile.(!!0)>>=mapM_(printf"%02X ").unpack.
nimi,

2

Rust, 141 byte (versione fornita)

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

Rust, 151 byte (versione originale)

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!()}

-10 byte: TIO
Herman L

2

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

Questa è una teoria teorica completa a questo punto. In realtà non puoi eseguirlo. Se tutto funziona secondo le sue specifiche, questo funzionerebbe, ma non tutto ancora.

Lo script bash è

]<$1

e il programma stax deve essere compilato e salvato in] ​​è

╛↕ßú┼_

Imposta il tuo set di caratteri su ISO 8859-1 (Windows-1252 non funzionerà qui) e vai

Disimballato e spiegato

_          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

2

Emojicode , 186 162 byte

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

Provalo online qui.

Ungolfed:

📦 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
    🍪
    ❗️❗️
  🍉
🍉

2

Perl 6 , 45 byte

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

Provalo online!

  • @*ARGS[0] è il primo argomento della riga di comando.
  • .IOtrasforma quel (presunto) nome file in un IO::Pathoggetto.
  • .slurp(:bin)legge l'intero file in un Bufbuffer di byte. (Senza il :bincontenuto del file verrebbe restituito come stringa Unicode.)
  • .list restituisce un elenco dei valori byte dal buffer.
  • .fmt('%02X')è un Listmetodo che formatta gli elementi dell'elenco utilizzando la stringa di formato specificata, quindi li unisce con spazi. (Conveniente!)
  • .say stampa quella stringa.

Sulla base della risposta di Python, un TIO Link è in effetti del tutto possibile.
Draco18s non si fida più di SE

Alcuni riorganismi possono rimuovere il .listper 41 byte
Jo King

1

D , 98 byte

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

Provalo online!



1

Racchetta, 144 byte

Questa presentazione genera uno spazio finale e nessuna nuova riga finale. Fammi sapere se questo è considerato una scappatoia :)

(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")))))

Pulito

(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")))))

1

Forth (gforth) , 71 byte

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

Provalo online!

TIO ha 3 argnell'ultima riga perché TIO passa "-e ciao" al parser della riga di comando prima di passare il codice

Spiegazione del codice

: 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

1

Javascript, 155 byte

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

1

VBScript, 143 byte

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

1

Wolfram Language (Mathematica) , 94 89 byte

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

Provalo online!

Il codice è abbastanza autoesplicativo a causa dei nomi lunghi dei comandi. Dovrebbe essere letto principalmente da destra a sinistra:

$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

1

Gema , 45 personaggi

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

Esecuzione di esempio:

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 

Provalo online!


1

Pyth , 12 byte

jdcr1.Hjb'w2

Provalo online!

Accetta input come prompt utente (nessun modo per accedere agli argomenti della riga di comando 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()

(*) Non sono sicuro al 100% se questo è previsto, ma una base di 256 cifre (come in, un carattere), si convertirà sempre in esattamente 2 cifre esadecimali, eliminando la necessità di riempire con zero.


1

Node.js, 118 byte

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

Come si presenta il risultato: inserisci qui la descrizione dell'immagine

A proposito, il contenuto test.txtdell'esempio è il seguente:

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

(Perché mai è necessario un output in maiuscolo. Ho dovuto aggiungere la conversione con toUpperCase(), e questo costa 13 byte.)


0

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

Provalo online!

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") + " ");
            }
        }
    }
}

1
Penso che ciò che segue salverà alcuni byte (ora 181 credo): usando System.IO; classe P {static void Main (string [] a) {if (a.Length> 0 && File.Exists (a [0]) ) {foreach (var b in File.ReadAllBytes (a [0])) {System.Console.Write ($ "{b.ToString (" X2 ")}");}}}}
PmanAce,

@PmanAce Se rimuovi parte degli spazi bianchi, si riduce a 175.
facepalm42

0

05AB1E , 18 byte

IvyÇh2j' 0.:' Jvy?

Provalo online!

Spiegazione:

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?
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.