Kürzestes Hex-Dumping-Programm

13

Herausforderung

Erstellen Sie ein Konsolenprogramm, um jedes Byte einer Datei anzuzeigen.


Gewinnen

Da dies , gewinnen die wenigsten Bytes.


Regeln

  • Das Programm muss eine Konsolenanwendung sein , dh, es wird von einer Art Befehlszeileninterpreter ausgeführt.
  • Jedes Byte muss hexadezimal in Großbuchstaben und durch ein Leerzeichen getrennt sein und aus zwei Ziffern bestehen. (setze die Zahl 0 davor, wenn es eine Ziffer hat)
  • Die Datei muss mit IO oder alternativ gelesen und nicht fest codiert werden.
  • Der Dateipfad muss als Befehlszeilenargument oder als Benutzeraufforderung (wie STDIN) angegeben werden .
  • Keine Lücken bitte ;

Beispiel

test.txt (endet mit LF)

Hello World!

$ ./hexdump.exe test.txt
48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0A
facepalm42
quelle
16
@ facepalm42 Um Facepalms zu vermeiden, empfehle ich dringend, die Sandbox zu verwenden, um zukünftige Herausforderungen zu entwerfen, bevor Sie sie veröffentlichen.
Adám
2
Wie ist es möglich, alle Bytewerte auf einmal anzuzeigen, wenn sie nicht auf den Bildschirm passen? Das Scrollen ist nicht "sofort". Was ist auch falsch daran, dass (eine Funktion) nur die Werte zurückgibt?
Adám
7
@ facepalm42 Bitte ändere die Spezifikation nicht so lange nach dem Posten der Challenge. Der ursprüngliche Beitrag enthielt keine genauen Angaben zum Format der Hexadezimalzahlen, was den Antwortenden überlassen blieb. Ihre letzte Änderung hat meine vorhandene Antwort ungültig gemacht!
Adám
11
Gibt es einen bestimmten Grund, warum Sie nur Befehlszeilenargumente oder eine Benutzeraufforderung zulassen? Was ist falsch daran, zB den Dateinamen als Funktionsargument zu nehmen?
Adám
3
Es wäre hilfreich, wenn Sie eine einfache hello.txtTextdatei als Beispiel als Eingabe hätten und wie die erwartete Ausgabe aussehen sollte. Wenn beispielsweise hello.txtdas Wort hellomit einem Zeilenumbruch enthalten wäre, wie würde dies in der Ausgabe ausgedrückt werden? Gruppieren Sie die Bytes in 16-Bit-, 32-Bit- oder 64-Bit-Wörtern? Oder wird jedes Byte als zweistelliges Hex ausgedrückt? Sind Leerzeichen nach jedem Byte als Hex oder nach jedem x-Bit-Wort zulässig? Benötigen Sie einen 0xPre-Fix für jedes Byte?
Shaun Bebbers

Antworten:

11

C (gcc) auf * nix, 73 71 Bytes

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

Probieren Sie es online! Testsuite

-2 Bytes dank Johan du Toit

Das hängt davon O_RDONLY == 0ab, int_one == 1wo int int_one; *(char*)&int_one = 1;.

wastl
quelle
11
69 Bytes ;)
Johan du Toit
6

Ruby , 26 Bytes

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

Probieren Sie es online!

GB
quelle
Liest dies den Inhalt einer Datei, wenn ein Dateipfad als Programmargument angegeben wird? Basierend auf dem TIO scheint es nur aus STDIN zu lesen, aber ich kenne Ruby nicht gut genug, um zu sagen, dass es falsch ist.
Kevin Cruijssen
1
@KevinCruijssen Ja, es werden die Dateipfade als Programmargument verwendet. Wenn keine Argumente vorhanden sind, wird $<stattdessen zum Lesen von STDIN gewechselt.
Wert Tinte
6

Java 11, 156 154 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 dank @Holger .

Probieren Sie es online mit./.input.tio als Argument den Dateipfad verwenden, der eine bestimmte Eingabe als Dateiinhalt enthält.

Erläuterung:

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
quelle
Was ist der Grund für die Verwendung von interfaceanstelle von class?
JakeDot
4
@JakeDot main muss public sein, Interface-Methoden sind immer public, interfaceist kürzer als class+ public.
Grimmy
3
Mit Java 11 können Sie Path.ofanstelle vonPaths.get
Holger
1
@ Holger Danke! :)
Kevin Cruijssen
2
@Grimy seit Java 9 sind Schnittstellenmethoden nicht immer public, aber es publicsei denn , sie werden explizit deklariert private.
Holger
6

PHP , 60 59 54 Bytes

<?=wordwrap(bin2hex(implode(file($argv[1]))),2,' ',1);
  • -1 Byte dank manassehkatz
  • -5 Bytes dank Blackhole

Probieren Sie es online!

John
quelle
1
Sollte in der Lage sein, das Trailing zu löschen ?>und 2 Bytes zu speichern, oder wenn das nicht funktioniert, ersetzen Sie es ?>durch ein Semikolon und speichern Sie 1 Byte.
Manassehkatz-Moving 2 Codidact
2
Verwenden Sie implode(file($x))anstelle von file_get_contents($x)(-4 Byte).
Blackhole
2
Und wordwrap()ist mit 1als letztem Parameter ein Byte kürzer als chunk_split().
Blackhole
5

Perl 5 ( -aF//), 23 Bytes

printf"%02X ",ord for@F

TIO

Nahuel Fouilleul
quelle
4

APL (Dyalog Unicode) , 16 Bytes

Anonyme implizite Präfixfunktion. Gibt eine zweizeilige Matrix zurück (und gibt diese implizit aus, wenn der Wert nicht anderweitig verwendet wird), wobei die oberen 4 Bits in der oberen Zeile als Dezimalzahl 0-15 und die unteren 4 Bits in der unteren Zeile auf ähnliche Weise dargestellt werden. Das heißt, die Matrix enthält so viele Spalten wie die Datei Bytes enthält.

16 1683 ¯1∘⎕MAP

Probieren Sie es online!

⎕MAP Ordnen Sie das Argument Dateiname einem Array
 mit Parametern zu:
¯1 Die gesamte Länge der Datei wird
83 als 8-Bit-Ganzzahl gelesen

16 16⊤ Konvertieren (Anti-Base) in 2-stelliges Hexadezimal

Adam
quelle
1
@ facepalm42 Es ist sehr viel in hexadezimaler Schreibweise. ZB Hist 72, was 4 × 16¹ + 8 × 16⁰ oder [4,8] ₁₆ ist. Daher lautet die erste Spalte im Beispiel [4,8].
Adám
Oh, ich habe es komplett vergessen! Es tut uns leid.
Facepalm42
4

Python 3, 59 Bytes

-11 Bytes dank Mostly Harmless!

-8 Bytes dank James K Polk!

-24 Bytes dank Blue!

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

Probieren Sie es online!

Das ist ziemlich einfach; Es öffnet einen Dateinamen, der als Eingabe in STDIN angegeben wurde, liest ihn, konvertiert jedes Zeichen in seinen ASCII-Wert, konvertiert jede Zahl in Hex, entfernt die "0x"hexadezimalen Werte vor Python, füllt den Wert bei Bedarf mit einer Null auf und fügt die Werte dann zusammen zusammen mit Leerzeichen.

Programmierer
quelle
Kann ein paar Bytes einsparen, '%02X'%ord(i)anstatt die Ausgabe von hex
Mostly Harmless
@MostlyHarmless Fertig! -11 Bytes. Vielen Dank!
mprogrammer
Wie wäre es mit '% 02X' anstelle von '% 02x' und loswerden.upper()
James Reinstate Monica Polk
Sie können die Bytes von speichern, import sysindem Sie stattdessen raw_input()als Dateinamen verwenden. Regeln ermöglichen Benutzeraufforderungen.
Blue
@Blau Danke! Und in Python 3 ist es noch kürzer, wo Sie es einfach machen könneninput()
mprogrammer
3

Bash ,  33  23 Bytes

... mit viel Hilfe:
-3 dank Manatwork
-4 dank Spuck
-3 dank Nahuel FOUILLEUL

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

Probieren Sie es online!

Beachten Sie, dass der obige TIO-Link Eingaben verwendet - wir können Dateien lokal schreiben, dies zeigt also, dass es als Programm arbeitet, das einen Dateipfad verwendet.

Jonathan Allan
quelle
Geringfügige Kürzungen: xxd -u -p $1|fold -2|tr \\n \ .
Manatwork
Vielen Dank, eine Idee, wie man das \nund \ in der 'this'-Link-Version zum Laufen bringt? EDIT: Ich habe ein weiteres Escape-Zeichen hinzugefügt.
Jonathan Allan
Wenn ich Sie richtig verstehe, möchten Sie nur von doppelten Anführungszeichen zu einfachen Anführungszeichen wechseln: Probieren Sie es online aus!
Manatwork
Großartig, danke!
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))}}

Try it online!

Edit: -11 bytes thanks to @ChrisParton

Edit: Working TIO

Edit: -1 byte thanks to @KevinCruijssen

Quinn
quelle
1
Could you ditch the import and reference File as java.io.File instead?
Chris Parton
@ChrisParton right you are, thanks!
Quinn
Here a working TIO. You can use ./.input.tio as file-path argument, and it will use the STDIN as file-content. :)
Kevin Cruijssen
@KevinCruijssen thanks! just updated answer
Quinn
1
I don't know Kotlin, but the TIO still works if I remove the space at a:Array, so I think you can save a byte.
Kevin Cruijssen
2

Dart, 140 134 bytes

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

Try it online!

-6 bytes because I forgot to reduce variable names

Elcan
quelle
+1 for dart. Such an underrated language.
vasilescur
Hard to golf with, since it's basically JS without the very lax type system
Elcan
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
quelle
1
Ein bisschen kürzer: import Data.ByteStringplus main=getArgs>>=Data.ByteString.readFile.(!!0)>>=mapM_(printf"%02X ").unpack.
Nimi
2

Rust, 141 bytes (contributed version)

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 bytes (original version)

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.
quelle
-10 Bytes: TIO
Herman L
2

Bash + Stax, 6 + 4 + 1 = 11 Bytes

Dies ist zu diesem Zeitpunkt ein vollständiges theoretisches Handwerk. Sie können das nicht ausführen. Wenn alles gemäß seiner Spezifikation funktioniert, würde dies funktionieren, aber noch nicht alles.

Das Bash-Skript lautet

]<$1

und das stax-programm muss kompiliert und gespeichert werden]

╛↕ßú┼_

Stellen Sie Ihren Zeichensatz auf ISO 8859-1 ein (Windows-1252 funktioniert hier nicht) und fahren Sie fort

Ausgepackt und erklärt

_          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
quelle
2

Emojicode , 186 162 Bytes

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

Probieren Sie es online aus hier aus.

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
    🍪
    ❗️❗️
  🍉
🍉
OOBalance
quelle
2

Perl 6 , 45 Bytes

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

Probieren Sie es online!

  • @*ARGS[0] ist das erste Befehlszeilenargument.
  • .IOverwandelt diesen (vermuteten) Dateinamen in ein IO::PathObjekt.
  • .slurp(:bin)Liest die gesamte Datei in einen BufByte-Puffer. (Ohne die :binDatei würde der Inhalt als Unicode-String zurückgegeben.)
  • .list gibt eine Liste der Bytewerte aus dem Puffer zurück.
  • .fmt('%02X')ist eine ListMethode, mit der die Elemente der Liste mit der angegebenen Formatzeichenfolge formatiert und anschließend mit Leerzeichen verbunden werden. (Praktisch!)
  • .say druckt diese Zeichenfolge.
Sean
quelle
Basierend auf der Python-Antwort ist ein TIO-Link in der Tat durchaus möglich.
Draco18s vertraut SE
Einige Neuanordnungen können die .listfür 41 Bytes
Jo King
1

Python 3, 75 Bytes

Meistens eine Kopie von Maxwells Python 2-Antwort.

import sys
print(' '.join('%02X'%b for b in open(sys.argv[1],'rb').read()))
James Reinstate Monica Polk
quelle
du meinst wahrscheinlich sys.argv[1]. mit sys.argv[0]diesem Skript funktioniert eher wie ein Quine ;-)
Anion
@anion: Hoppla, haha, reparieren ...
James Reinstate Monica Polk
1

Schläger, 144 Bytes

Diese Übermittlung gibt ein Leerzeichen und keine Zeilenumbrüche aus. Lass es mich wissen, wenn dies eine Lücke ist :)

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

Aufgeräumt

(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
quelle
1

Viertens (gviertens) , 71 Bytes

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

Probieren Sie es online!

TIO hat 3 argin der letzten Zeile, weil TIO "-e bye" an den Kommandozeilen-Parser übergibt, bevor der Code übergeben wird

Code Erklärung

: 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
quelle
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
quelle
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
quelle
1

Wolfram Language (Mathematica) , 94 89 Bytes

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

Probieren Sie es online!

Der Code ist aufgrund der langen Befehlsnamen selbsterklärend. Es sollte meistens von rechts nach links gelesen werden:

$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
römisch
quelle
1

Gema , 45 Zeichen

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

Probelauf:

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 

Probieren Sie es online!

Mann bei der Arbeit
quelle
1

Pyth , 12 Bytes

jdcr1.Hjb'w2

Probieren Sie es online!

Nimmt Eingaben als Benutzeraufforderung entgegen (kein Zugriff auf Befehlszeilenargumente 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()

(*) Ich bin mir nicht zu 100% sicher, ob dies beabsichtigt ist, aber eine 256-stellige Basis (wie in einem Zeichen) wird immer in genau 2 Hexadezimalziffern umgewandelt, sodass keine Nullen aufgefüllt werden müssen.

ar4093
quelle
1

Node.js, 118 Bytes

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

Wie das Ergebnis aussieht: Bildbeschreibung hier eingeben

Übrigens ist der Inhalt des test.txtBeispiels wie folgt:

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

(Warum um alles in der Welt ist die Ausgabe in Großbuchstaben notwendig. Ich musste die Konvertierung mit hinzufügen toUpperCase(), und das kostet 13 Bytes.)

Shieru Asakoto
quelle
0

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

Probieren Sie es 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") + " ");
            }
        }
    }
}
facepalm42
quelle
1
Ich denke, das Folgende spart einige Bytes (jetzt glaube ich 181): using System.IO; class P {statische Leere 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 Wenn Sie etwas Leerzeichen entfernen, wird es auf 175 gesenkt.
facepalm42
0

05AB1E , 18 Bytes

IvyÇh2j' 0.:' Jvy?

Probieren Sie es online!

Erläuterung:

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
quelle