十六进制转储您的源代码


15

在进行代码搜寻时,有时需要使用十六进制转储代码,通常是因为您使用了无法打印的字符。那么,为什么不编写一个十六进制转储本身的程序呢?

挑战

面临的挑战是,在没有任何输入的情况下,以以下格式输出源代码的十六进制转储:

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  ................

或者,例如,如果您的程序是 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)

细节

十六进制转储分为三部分,每行代表源代码的16个字节。

第一部分是内存地址。它指定当前行在代码中的开始位置。写为2字节的十六进制数字,后跟一个:,然后是一个空格。

第二,是十六进制转储本身。这是您的源代码的16个字节,以十六进制形式写,用空格分隔。这应该是使用代码编码的准确字节表示形式。

最后,在两个空格之后,是代码本身。这只是您代码的16个字符,不可打印字符写为.

笔记

  • 一个的挑战,所以标准奎因规则适用。
  • 这也是挑战,因此适用标准漏洞
  • 如第二个示例所示,请勿在EOF之后写入字节,而应使用空格。
  • 尾随空格很好。
  • 如果您碰巧有这种特定格式的内置到十六进制转储的文件,则不会被禁止,而是会皱眉。
  • 不可打印字符是指仅表示为单个字节而不能表示为单个间距的字形的任何字符。为UTF-8,此装置0-31128-255。对于“ 果冻代码页”,由于所有字符都可以表示为单个间距的字形,因此没有不可打印字符。


就个人而言,我觉得这是一个实用的粗绳,使它与众不同,但是我很愿意看到社区的想法。
ATaco

1
记录下来,您看不到文件名xxd吗?
Rɪᴋᴇʀ

4
当然不是,标准奎因规则不允许这样做
ATaco

1
就个人而言,我会留待答案。我认为完全没有必要因此排除某种语言。如果您坚持使用固定宽度,则应使用大多数语言都应该足够的字体。大多数hexdump实用程序使用7个十六进制数字。
丹尼斯

Answers:


3

V,39个字节

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

在线尝试!

请注意,通常V使用latin1编码,其中为36字节(这是TIO所说的),但是此提交使用的是UTF-8,其中为39字节。

这几乎只是我写的V-quine模板的修改。


是否应该0a删除输出末尾的换行符?
Kritixi Lithos

@kritixilithos啊,我忘记了。在末尾添加换行符会更容易。
DJMcMayhem

8

Perl,81个字节

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

把shebang算作一个。将代码长度设置为16的倍数可以节省很多格式化时间。使用eval重新分配$_将自己从借来ais523

输出:

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

在线尝试!


5

Perl + xxd + cut,61个字节

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

在线尝试!

这是Perl中的通用quine构造函数+调用xxdcut执行hexdumping。所讨论的程序均未内置以所讨论格式进行十六进制转储的功能;但是,xxd -g1距离非常近,因此可以使用cut将输出修整为正确的形状。

通用quine构造函数是$_=q("\$_=q($_);eval");eval,它在内存中创建其自己的源代码的副本,并且可以对其进行修改以对其执行任意操作。在这种情况下,我使用open "|"并将print输入通过管道传递到外部程序,xxd该程序完成了大部分的十六进制转储工作,并将cut其更改为所需的格式。


3

的JavaScript(ES6)229个 219 162字节

感谢@Neil节省了大量字节

注意

不少人认为以我的方式访问函数的源代码是一种作弊行为,但根据@Dennis的说法,这很好。因此,我将在这里留下答案。

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`

用法

f()

只需调用不带参数的函数即可。

输出量

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`                                     

1
(不知道那是F ='+ F是根据标准奎因规则所允许,但如果它是那么对于161字节,我给你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`
尼尔

聪明的方法。我读了一些问题,并且似乎人们普遍认为这是作弊行为,因为我滥用了便捷的语言功能。我将其与您的改进代码一起添加到我的答案中。
路加福音

我认为这是允许的,Dennis在另一个quine挑战中说,使用函数源检查很好,而且我知道几个“ Golf a quine”答案都使用此功能。
FlipTack

改变第一.toString[t=toString]与第二到[t]保存3个字节。更改<backtick>\n<backtick><backtick><newline><backtick>拯救另一个。
user2428118

更改它的字符串方法要求函数名称为字符串,这样,它仅保存一个字节。至于换行符,将导致a十六进制转储中的,需要在前面加上0,并且添加该检查只会增加字节数。
路加福音

2

Ruby,128 112字节

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}'

没有尾随换行符。

感谢primo提出的对齐16字节边界的想法。

输出量

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}'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.