Programa de despejo hexadecimal mais curto

13

Desafio

Crie um programa de console para exibir cada byte de um arquivo.


Ganhando

Como se trata de , o menor número de bytes vence.


Regras

  • O programa deve ser um aplicativo de console , o que significa que será executado a partir de algum tipo de interpretador de linha de comando;
  • Cada byte deve estar em maiúsculas hexadecimal, separado por um espaço e deve ter 2 dígitos; (coloque o número 0 antes, se tiver 1 dígito)
  • O arquivo deve ser lido usando IO ou alternativa e não codificado;
  • O caminho do arquivo deve ser especificado como um argumento da linha de comandos ou um prompt do usuário (como STDIN) ;
  • Não há brechas, por favor ;

Exemplo

test.txt (termina com LF)

Hello World!

$ ./hexdump.exe test.txt
48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0A
facepalm42
fonte
16
@ facepalm42 Para evitar os facepalms, recomendo fortemente o uso da Sandbox para ajudar a projetar desafios futuros antes de publicá-los.
Adám 09/07/19
2
Como é possível exibir todos os valores de bytes de uma só vez, se não couberem na tela? A rolagem claramente não é "de uma só vez". Além disso, o que há de errado com (uma função) apenas retornando os valores?
Adám 09/07/19
7
@ facepalm42 Por favor, não altere as especificações por muito tempo depois de postar o desafio. A postagem original não especificou o formato exato dos números hexadecimais, deixando para os respondentes. Sua edição mais recente invalidou minha resposta existente!
Adám 09/07/19
11
Existe um motivo específico para você permitir apenas argumentos de linha de comando ou um prompt do usuário? O que há de errado em, por exemplo, tomar o nome do arquivo como argumento de função?
Adám 9/07/19
3
Seria útil se você tivesse um hello.txtarquivo de texto simples como exemplo como entrada e qual deveria ser a saída esperada. Por exemplo, se hello.txtcontivesse simplesmente a palavra hellocom uma quebra de linha, como isso seria expresso na saída? Você está agrupando os bytes em palavras de 16, 32 ou 64 bits? Ou cada byte é expresso como hexadecimal de dois dígitos? Os espaços são aceitáveis ​​após cada byte como hexadecimal ou após cada palavra de bit x? Você precisa de uma 0xpré-correção para cada byte?
Shaun Bebbers 9/07/19

Respostas:

11

C (gcc) em * nix, 73 71 bytes

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

Experimente online! Suíte de teste

-2 bytes graças a Johan du Toit

Isso depende O_RDONLY == 0de int_one == 1onde int int_one; *(char*)&int_one = 1;.

wastl
fonte
11
69 Bytes ;)
Johan du Toit
6

Ruby , 26 bytes

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

Experimente online!

GB
fonte
Isso lê o conteúdo de um arquivo, dado o caminho do arquivo como argumento do programa? Com base no TIO, parece ler apenas do STDIN, mas não conheço Ruby o suficiente para dizer que está incorreto.
Kevin Cruijssen 10/07/19
1
@KevinCruijssen Sim, ele usa o (s) caminho (s) do arquivo como argumento do programa. Se não houver argumentos, $<alterne para a leitura de STDIN.
Value Ink
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 graças a @Holger .

Experimente online usando ./.input.tiocomo argumento caminho do arquivo, que terá uma entrada específica como conteúdo do arquivo.

Explicação:

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
fonte
Qual é a lógica por trás do uso em interfacevez de class?
JakeDot 10/07/19
4
O @JakeDot main deve ser público, os métodos de interface são sempre públicos, interfacesão mais curtos que class+ public.
Grimmy
3
Com o Java 11, você pode usar em Path.ofvez dePaths.get
Holger
1
@ Holger Obrigado! :)
Kevin Cruijssen 10/07/19
2
@Grimy desde o Java 9, os métodos de interface nem sempre são public, mas são, a publicmenos que declarados explicitamente private.
Holger
6

PHP , 60 59 54 bytes

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

Experimente online!

John
fonte
1
Deve ser capaz de descartar o final ?>e salvar 2 bytes ou, se isso não funcionar, substitua ?>por um ponto-e-vírgula e salve 1 byte.
manassehkatz-Movendo 2 Codidact
2
Use em implode(file($x))vez de file_get_contents($x)(-4 bytes).
Blackhole
2
E wordwrap(), com 1o último parâmetro, é um byte menor que chunk_split().
Blackhole
5

Perl 5 ( -aF//), 23 bytes

printf"%02X ",ord for@F

TIO

Nahuel Fouilleul
fonte
4

APL (Dyalog Unicode) , 16 bytes

Função de prefixo tácito anônimo. Retorna (e imprime implicitamente, se o valor não for consumido de outra forma) uma matriz de duas linhas com os 4 bits superiores representados como um número decimal de 0 a 15 na linha superior e os 4 bits inferiores representados da mesma forma na linha inferior. Ou seja, a matriz possui tantas colunas quanto o arquivo possui bytes.

16 1683 ¯1∘⎕MAP

Experimente online!

⎕MAP mapeie o nome do arquivo do argumento para uma matriz
 com parâmetros:
¯1 todo o comprimento do arquivo
83 lido como números inteiros de 8 bits

16 16⊤ converter (anti-base) em hexadecimal de 2 posições

Adão
fonte
1
@ facepalm42 É muito em hexadecimal. Por exemplo H, 72 é 4 × 16 4 + 8 × 16⁰ ou [4,8] ,8. Portanto, a primeira coluna no exemplo é lida [4,8].
Adám 09/07/19
Ah, eu esqueci completamente! Desculpe.
facepalm42
4

Python 3, 59 bytes

-11 bytes graças a Mostly Harmless!

-8 bytes graças a James K Polk!

-24 bytes graças ao Blue!

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

Experimente online!

Isso é bem direto; abre um nome de arquivo fornecido como entrada no STDIN, lê, converte cada caractere em seu valor ASCII, converte cada número em hexadecimal, retira o "0x"que precede os valores hexadecimais em Python, preenche o valor com zero, se necessário, e une os valores junto com espaços.

mprogrammer
fonte
Pode economizar alguns bytes com '%02X'%ord(i), em vez de cortar a saída do hex
na maior parte inofensiva
@MostlyHarmless Done! -11 bytes. Obrigado!
Mprogrammer 10/07/19
que tal '% 02X' em vez de '% 02x' e se livre de.upper()
Presidente James Moveon Polk 10/07/19
Você pode salvar os bytes do import sysusando raw_input()como o nome do arquivo; regras permitem que o usuário solicite.
Azul
@Blue Thanks! E é ainda mais curto no Python 3, onde você pode simplesmente fazerinput()
mprogrammer
3

Bash ,  33  23 bytes

... com muita ajuda:
-3 graças a manatwork
-4 graças a spuck
-3 graças a Nahuel Fouilleul

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

Experimente online!

Observe que o link TIO acima usa entrada - podemos escrever arquivos localmente, portanto isso mostra que ele funciona como um programa que segue um caminho de arquivo.

Jonathan Allan
fonte
Reduções menores: xxd -u -p $1|fold -2|tr \\n \ .
manatwork
Obrigado, alguma idéia de como obter \ne \ trabalhar na versão do link 'this'? Edição: eu adicionei outro caractere de escape.
Jonathan Allan
Se entendi bem, você só quer mudar de aspas duplas para aspas simples: Experimente on-line!
9139 manatwork
Perfeito, obrigado!
Jonathan Allan
xxd -c1 -p -u $1|tr \\n \
spuck 10/07/19
3

Kotlin , 130 127 104 93 92 bytes

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

Experimente online!

Edit: -11 bytes graças a @ChrisParton

Edit: Working TIO

Edit: -1 byte graças a @KevinCruijssen

Quinn
fonte
1
Você poderia abandonar a importação e referência Filecomo java.io.Fileem vez disso?
Chris Parton
@ChrisParton você está certo, obrigado!
Quinn
Aqui está um TIO de trabalho. Você pode usar ./.input.tiocomo argumento do caminho do arquivo e ele usará o STDIN como conteúdo do arquivo. :)
Kevin Cruijssen 10/07/19
@KevinCruijssen thanks! resposta atualizada
Quinn
1
Não conheço Kotlin, mas o TIO ainda funcionará se eu remover o espaço em a:Array, então acho que você pode salvar um byte.
Kevin Cruijssen 10/07/19
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(' '));}

Experimente online!

-6 bytes porque esqueci de reduzir nomes de variáveis

Elcan
fonte
+1 para dardo. Uma linguagem tão subestimada.
vasilescur 9/07/19
Difícil de golfe com, já que é basicamente JS sem o sistema de tipo muito frouxa
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
fonte
1
Um pouco mais curto: import Data.ByteStringmais main=getArgs>>=Data.ByteString.readFile.(!!0)>>=mapM_(printf"%02X ").unpack.
nimi
2

Ferrugem, 141 bytes (versão contribuída)

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

Ferrugem, 151 bytes (versão 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.
fonte
-10 bytes: TIO
Herman L
2

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

Este é um ofício teórico completo neste momento. Você não pode realmente executar isso. Se tudo funcionar de acordo com suas especificações, isso funcionaria, mas nem tudo ainda funciona.

O script bash é

]<$1

eo programa stax deve ser compilado e salvo em] é

╛↕ßú┼_

Defina seu conjunto de caracteres para ISO 8859-1 (Windows-1252 não funcionará aqui) e vá

Desembalado e 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
fonte
2

Emojicode , 186 162 bytes

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

Experimente online aqui.

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
fonte
2

Perl 6 , 45 bytes

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

Experimente online!

  • @*ARGS[0] é o primeiro argumento da linha de comandos.
  • .IOtransforma esse nome de arquivo (presumido) em um IO::Pathobjeto.
  • .slurp(:bin)lê o arquivo inteiro em um Bufbuffer de bytes. (Sem o :binarquivo, o conteúdo seria retornado como uma string Unicode.)
  • .list retorna uma lista dos valores de bytes do buffer.
  • .fmt('%02X')é um Listmétodo que formata os elementos da lista usando a sequência de formato fornecida e os une a espaços. (Conveniente!)
  • .say imprime essa sequência.
Sean
fonte
Com base na resposta do Python, um TIO Link é realmente possível.
Draco18s não confia mais em SE
Alguns reorganização pode remover o .listpara 41 bytes
Jo rei
1

D , 98 bytes

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

Experimente Online!

Samuel
fonte
1

Python 3, 75 bytes

Principalmente uma cópia da resposta python 2 de Maxwell.

import sys
print(' '.join('%02X'%b for b in open(sys.argv[1],'rb').read()))
Presidente James Moveon Polk
fonte
você quer dizer provavelmente sys.argv[1]. com sys.argv[0]esse script funciona mais como uma Quine ;-)
ânion
@anion: oops, haha, consertando ...
Presidente James Moveon Polk
1

Raquete, 144 bytes

Esse envio gera um espaço à direita e nenhuma nova linha à direita. Deixe-me saber se isso é considerado uma brecha :)

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

Limpo

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

Quarto (gforth) , 71 bytes

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

Experimente online!

O TIO está 3 argna última linha porque o TIO passa "-e bye" para o analisador de linha de comando antes de passar o código

Código Explicação

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

Wolfram Language (Mathematica) , 94 89 bytes

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

Experimente online!

O código é bastante auto-explicativo por causa dos nomes de comando longos. Deve ser lido principalmente da direita para a esquerda:

$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
fonte
1

Gema , 45 caracteres

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

Exemplo de execução:

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 

Experimente online!

homem a trabalhar
fonte
1

Pitão , 12 bytes

jdcr1.Hjb'w2

Experimente online!

Recebe entrada como prompt do usuário (nenhuma maneira de acessar os argumentos da linha de 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()

(*) Não tenho 100% de certeza se isso é pretendido, mas um dígito básico de 256 dígitos (como em um caractere) sempre será convertido em exatamente 2 dígitos hexadecimais, eliminando a necessidade de zerar.

ar4093
fonte
1

Node.js, 118 bytes

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

Como é o resultado: insira a descrição da imagem aqui

Entre o conteúdo do test.txtexemplo é o seguinte:

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

(Por que diabos a saída em maiúscula é necessária. Eu tive que adicionar a conversão com toUpperCase(), e isso custou 13 bytes.)

Shieru Asakoto
fonte
0

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

Experimente 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
fonte
1
Eu acho que o seguinte salvará alguns bytes (agora eu acho): using System.IO; class P {static void Main (string [] a) {if (a.Length> 0 && File.Exists (a [0]) ) {foreach (var b em File.ReadAllBytes (a [0])) {System.Console.Write ($ "{b.ToString (" X2" )} ");}}}}
PmanAce
@PmanAce Se você remover alguns dos espaços em branco, se chega até 175.
facepalm42
0

05AB1E , 18 bytes

IvyÇh2j' 0.:' Jvy?

Experimente online!

Explicação:

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
fonte