Hex Dump seu código-fonte

15

Ao jogar golfe com código, haverá momentos em que você precisará de um Hex Dump do seu código, geralmente porque você usou caracteres não imprimíveis. Então, por que não criar um programa que o Hex Dumps em si?

O desafio

Esse desafio é, sem nenhuma entrada, gerar um Hex Dump do seu código-fonte na seguinte formatação:

0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

Ou, por exemplo, se seu programa foi print("SomeString"):rep(123)

0000: 70 72 69 6e 74 28 5c 22 53 6f 6d 65 53 74 72 69  print("SomeStrin
0010: 6e 67 5c 22 29 3a 72 65 70 28 31 32 33 29        g"):rep(123)

Específicos

O dump hexadecimal é dividido em linhas de três partes, cada linha representando 16 bytes do seu código-fonte.

A primeira parte é o endereço da memória. Ele especifica onde a linha atual começa no seu código. Escrito como um número hexadecimal de 2 bytes, seguido por um: , em seguida, um espaço.

O segundo, é o próprio Hex Dump. São 16 bytes do seu código-fonte, escritos em formato hexadecimal, separados por espaços. Essa deve ser uma representação precisa de bytes, usando a codificação do seu código.

Por fim, após uma lacuna de dois espaços, é o próprio código. São apenas 16 caracteres do seu código, com caracteres não imprimíveis escritos como.

Notas

  • Este é um desafio , então Regras de Quine padrão se aplicam.
  • E esse também é desafio do , então brechas padrão se aplicam.
  • Conforme mostrado no segundo exemplo, não escreva bytes após o EOF, use espaço em branco.
  • O espaço em branco à direita é bom.
  • Inbuilts para Hex dump, se houver um nesse formato específico, não são proibidos, mas são mal vistos.
  • Caracteres não imprimíveis se referem a qualquer caractere que, representado como apenas um byte, não pode ser representado como um glifo com espaçamento único. Para UTF-8, este meio 0-31, 128-255. Para a página de código Jelly , como todos os caracteres podem ser representados como um glifo com espaçamento único, não há caracteres não imprimíveis.
ATaco
fonte
relacionado / duplicado? codegolf.stackexchange.com/q/11985/47022
Herb Wolfe
Pessoalmente, sinto que essa é uma solução aplicada que o torna diferente o suficiente, mas estou disposto a ver os pensamentos da comunidade.
ATaco 16/01
1
Então, para o registro, você não pode ler o nome do arquivo e xxdele?
Rɪᴋᴇʀ
4
Claro que não, as regras padrão de Quine não permitem isso
ATaco 16/01
1
Pessoalmente, eu deixaria isso para a resposta. Excluir um idioma por causa disso é absolutamente desnecessário na minha opinião. Se você insistir em uma largura fixa, use algo que seja suficiente para a maioria dos idiomas. A maioria dos utilitários hexdump usa 7 dígitos hexadecimais.
Dennis

Respostas:

3

V , 39 bytes

ñi241"qp:%!xxd
Î4x
Íøø / &
f&3i ÿ

Experimente online!

Observe que normalmente o V usa a codificação latin1, onde são 36 bytes (que é o que diz o TIO), mas esse envio está usando UTF-8, onde são 39 bytes.

Isso é apenas uma modificação do modelo V-quine sobre o qual escrevi.

DJMcMayhem
fonte
A nova linha 0ano final da saída não deve ser removida?
Kritixi Lithos
@kritixilithos Ah, eu esqueci disso. É mais fácil adicionar uma nova linha ao final.
DJMcMayhem
8

Perl, 81 bytes

#!perl -l
$_=q($%+=print"00$%0: @{[unpack'(H2)*']}  $_"for"\$_=q($_);eval"=~/.{16}/g);eval

Contando o shebang como um. O fato de o comprimento do código ser múltiplo de 16 economiza bastante na formatação. Usando evalpara reatribuir $_para si mesmo emprestado do ais523 .

Resultado:

0000: 24 5f 3d 71 28 24 25 2b 3d 70 72 69 6e 74 22 30  $_=q($%+=print"0
0010: 30 24 25 30 3a 20 40 7b 5b 75 6e 70 61 63 6b 27  0$%0: @{[unpack'
0020: 28 48 32 29 2a 27 5d 7d 20 20 24 5f 22 66 6f 72  (H2)*']}  $_"for
0030: 22 5c 24 5f 3d 71 28 24 5f 29 3b 65 76 61 6c 22  "\$_=q($_);eval"
0040: 3d 7e 2f 2e 7b 31 36 7d 2f 67 29 3b 65 76 61 6c  =~/.{16}/g);eval

Experimente online!

primo
fonte
5

Perl + xxd + cut, 61 bytes

$_=q(open F,"|xxd -g1|cut -c5-";print F"\$_=q($_);eval");eval

Experimente online!

Este é um construtor universal de quine no Perl + uma chamada para xxde cutpara fazer o hexdumping. Nenhum dos programas em questão possui um built-in para executar um hexdump no formato da pergunta; no entanto, xxd -g1chega muito perto e, portanto, é possível usarcut para aparar a saída na forma correta.

O construtor de quine universal é $_=q("\$_=q($_);eval");eval, que cria uma cópia de seu próprio código-fonte na memória e pode ser modificado para executar operações arbitrárias nele. Nesse caso, eu uso open "|"e canalizo printa entrada para programas externos, xxdque executam a maior parte do trabalho de hexdumping e o cutalteram para o formato necessário.


fonte
3

JavaScript (ES6) 229 219 162 bytes

Obrigado a @Neil por salvar muitos bytes

Nota

Muitas pessoas acham que acessar o código fonte de uma função do jeito que eu faço isso é trapaça, mas de acordo com @Dennis, tudo bem. Como tal, deixarei minha resposta aqui.

Código

f=_=>([...c=`f=`+f].map(d=>d.charCodeAt()[t=`toString`](16)).join‌​` `+` `.repeat(46)).match(/.{48}/g).map((s,i)=>`00${i[t](16)}0: `+s+c.substr(i*16,16)).join`\n`

Uso

f()

Simplesmente chame a função sem argumentos.

Resultado

0000: 66 3d 5f 3d 3e 28 5b 2e 2e 2e 63 3d 60 66 3d 60 f=_=>([...c=`f=`
0010: 2b 66 5d 2e 6d 61 70 28 63 3d 3e 63 2e 63 68 61 +f].map(c=>c.cha
0020: 72 43 6f 64 65 41 74 28 29 5b 74 3d 60 74 6f 53 rCodeAt()[t=`toS
0030: 74 72 69 6e 67 60 5d 28 31 36 29 29 2e 6a 6f 69 tring`](16)).joi
0040: 6e 60 20 60 2b 60 20 60 2e 72 65 70 65 61 74 28 n` `+` `.repeat(
0050: 34 36 29 29 2e 6d 61 74 63 68 28 2f 2e 7b 34 38 46)).match(/.{48
0060: 7d 2f 67 29 2e 6d 61 70 28 28 73 2c 69 29 3d 3e }/g).map((s,i)=>
0070: 60 30 30 24 7b 69 5b 74 5d 28 31 36 29 7d 30 3a `00${i[t](16)}0:
0080: 20 60 2b 73 2b 63 2e 73 75 62 73 74 72 28 69 2a  `+s+c.substr(i*
0090: 31 36 2c 31 36 29 29 2e 6a 6f 69 6e 60 5c 6e 60 16,16)).join`\n`                                     
Lucas
fonte
1
(não tenho certeza de que 'f =' + f é permitido sob as regras padrão do quine, mas se for então para 161 bytes, eu dou a você f=_=>([...c=`f=`+f].map(c=>c.charCodeAt().toString(16)).join` `+` `.repeat(46)).match(/.{48}/g).map((s,i)=>`00`+i.toString(16)+`0 `+s+c.substr(i*16,16)).join`\n`.)
Neil
Abordagem inteligente. Eu li algumas perguntas e parece que as pessoas geralmente pensam que é considerado trapaça porque estou abusando de um recurso conveniente de linguagem. Acrescentarei isso, junto com o seu código aprimorado, à minha resposta.
Lucas
Eu acho que é permitido, disse Dennis, em outro desafio do quine, que o uso da inspeção da fonte de função é bom, e eu sei que várias respostas "Golf a quine" usam isso.
FlipTack
Altere o primeiro .toStringpara [t=toString]e o segundo [t]para salvar 3 bytes. Mude <backtick>\n<backtick>para <backtick><newline><backtick>para salvar outro.
precisa saber é o seguinte
Alterando-o pelo método string, o nome da função é uma string; portanto, ele salva apenas um byte. Quanto à nova linha, isso resultaria em um adump hexadecimal, que precisa de um 0 acrescentado e a adição dessa verificação aumentaria apenas o número de bytes.
Lucas
2

Ruby, 128 112 bytes

eval b='7.times{|y|$><<"%04x:"%y*=16;c=("eval b="+(a=39.chr)+b+a)[y,16];c.chars{|x|$><<" %x"%x.ord};puts"  "+c}'

Sem nova linha final.

Obrigado primo pela idéia de alinhar ao limite de 16 bytes.

Resultado

0000: 65 76 61 6c 20 62 3d 27 37 2e 74 69 6d 65 73 7b  eval b='7.times{
0010: 7c 79 7c 24 3e 3c 3c 22 25 30 34 78 3a 22 25 79  |y|$><<"%04x:"%y
0020: 2a 3d 31 36 3b 63 3d 28 22 65 76 61 6c 20 62 3d  *=16;c=("eval b=
0030: 22 2b 28 61 3d 33 39 2e 63 68 72 29 2b 62 2b 61  "+(a=39.chr)+b+a
0040: 29 5b 79 2c 31 36 5d 3b 63 2e 63 68 61 72 73 7b  )[y,16];c.chars{
0050: 7c 78 7c 24 3e 3c 3c 22 20 25 78 22 25 78 2e 6f  |x|$><<" %x"%x.o
0060: 72 64 7d 3b 70 75 74 73 22 20 20 22 2b 63 7d 27  rd};puts"  "+c}'
GB
fonte