最短的十六进制转储程序


13

挑战

创建一个控制台程序以显示文件的每个字节。


获奖

由于这是,因此最少的字节获胜。


规则

  • 程序必须是控制台应用程序,这意味着它将从某种命令行解释器运行;
  • 每个字节必须为大写十六进制,并以空格分隔,并且必须为2位数字。(如果有1位数字,则将数字0放在前面)
  • 必须使用IO或其他方式读取文件,并且不进行硬编码;
  • 文件路径必须指定为命令行参数或用户提示符(如STDIN)
  • 请没有漏洞 ;

test.txt(以LF结尾)

Hello World!

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

16
@ facepalm42为避免出现面孔问题,我强烈建议您使用沙箱帮助您在发布挑战之前设计未来的挑战。
亚当

2
如果屏幕上不适合显示所有字节值,怎么办?滚动显然不是“一次”。另外,仅返回值的(函数)有什么问题?
亚当

7
@ facepalm42发布挑战后,请不要长时间更改规格。原始帖子未指定十六进制数字的确切格式,而是由应答者决定。您最近的修改使我现有的答案无效!
亚当

11
您是否仅允许使用命令行参数或用户提示,是否有特定原因?例如将文件名作为函数参数有什么问题?
亚当

3
如果您有一个简单的hello.txt文本文件作为输入示例,并且预期的输出应该是有用的。例如,如果hello.txt仅包含hello带有换行符的单词,那么在输出中将如何表示呢?您将字节分为16位,32位还是64位字?还是每个字节都用两位十六进制表示?每个字节之后的十六进制或每个x位字之后的空格是否可以接受?您是否需要0x每个字节一个前缀?
Shaun Bebbers

Answers:



6

Ruby,26个字节

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

在线尝试!


这是否在给定文件路径作为程序参数的情况下读取文件的内容?基于TIO,它似乎只是从STDIN中读取的,但是我不知道Ruby是否足够好说这是不正确的。
凯文·克鲁伊森

1
@KevinCruijssen是的,它将文件路径作为程序参数。如果没有参数,则$<改为从STDIN读取。
价值墨水


6

爪哇11,156个 154字节

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个字节,感谢@Holger

通过使用./.input.tiofile-path作为参数在线尝试它,它将具有给定的输入作为file-content。

说明:

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

使用interface代替的原理是class什么?
JakeDot

4
@JakeDot main必须是公共的,接口方法始终是公共的,interfaceclass+ 短public
Grimmy

3
使用Java 11,您可以使用Path.of代替Paths.get
Holger

1
@霍尔格谢谢!:)
Kevin Cruijssen

2
@Grimy自Java 9起,接口方法并非总是如此public,但public除非明确声明,否则它们是必需的private
Holger

6

PHP60 59 54字节

<?=wordwrap(bin2hex(implode(file($argv[1]))),2,' ',1);
  • -1字节感谢manassehkatz
  • -5字节归功于Blackhole

在线尝试!


1
应该能够删除尾随?>并保存2个字节,或者如果不起作用,则替换?>为分号并保存1个字节。
manassehkatz-Moving 2 Codidact '19

2
使用implode(file($x))代替file_get_contents($x)(-4个字节)。
黑洞(Blackhole)

2
并且wordwrap()1作为最后一个参数,比短一个字节chunk_split()
黑洞


4

APL(Dyalog Unicode),16字节

匿名默认前缀功能。返回(如果不使用该值,则隐式打印)一个两行矩阵,其高4位在顶行中表示为十进制数字0-15,低4位在底行中类似表示。也就是说,矩阵具有与文件具有字节一样多的列。

16 1683 ¯1∘⎕MAP

在线尝试!

⎕MAP 将参数文件名映射到
 带有参数的数组:
¯1 文件的整个长度
83 读取为8位整数

16 16⊤ 将(反基数)转换为2位十六进制


1
@ facepalm42非常用十六进制表示。例如H:72,即4×16 1 + 8×16或[4,8]。因此,示例中的第一列显示为[4,8]
亚当

哦,我完全忘记了!抱歉。
facepalm42

4

Python 3,59个字节

-11个字节,多亏了无害!

-8个字节感谢James K Polk!

-24字节感谢Blue!

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

在线尝试!

这非常简单;它打开在STDIN上输入的文件名,读取文件,将每个字符转换为ASCII值,将每个数字转换为十六进制,"0x"在Python中去除十六进制值之前的,在必要时将值填充为零,然后将其连接连同空格。


可以节省一些字节,'%02X'%ord(i)而不用对十六进制的输出进行切片
无害的

@MostlyHarmless完成!-11个字节。谢谢!
mprogrammer

“%02X”而不是“%02x”怎么样,并摆脱.upper()

您可以import sys使用raw_input()代替文件名来保存字节。规则允许用户提示。
蓝色

@Blue谢谢!而且它在Python 3中甚至更短,您可以在其中做input()
mprogrammer19年

3

Bash 33  23字节

...在很多帮助下:
-3感谢manatwork
-4感谢spuck
-3感谢Nahuel Fouilleul

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

在线尝试!

请注意,上面的TIO链接使用输入-我们可以在本地写入文件,因此表明它可以像使用文件路径的程序一样工作。


小幅度减少:xxd -u -p $1|fold -2|tr \\n \
manatwork '19

谢谢,您知道如何在“此”链接版本中获得\n\ 工作吗?编辑:我添加了另一个转义字符。
乔纳森·艾伦,

如果我理解正确,那么您只想从双引号改为单引号:在线尝试!
manatwork '19

太棒了,谢谢你!
乔纳森·艾伦,

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

3

科特林130个 127 104 93 92字节

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

在线尝试!

编辑:-11字节感谢@ChrisParton

编辑:工作TIO

编辑:-1字节感谢@KevinCruijssen


1
File可以java.io.File代替导入和引用吗?
克里斯·帕顿

@ChrisParton对了,谢谢!
奎因,

这里是工作TIO。您可以将其./.input.tio用作文件路径参数,它将使用STDIN作为文件内容。:)
Kevin Cruijssen

@KevinCruijssen谢谢!刚刚更新的答案
奎因

1
我不了解Kotlin,但是如果删除处的空格,TIO仍然可以工作a:Array,因此我认为您可以节省一个字节。
凯文·克鲁伊森

2

140个 134字节

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

在线尝试!

-6个字节,因为我忘了减少变量名


+1飞镖。如此低估的语言。
vasilescur

很难打高尔夫,因为它基本上是JS,没有非常宽松的类型系统
Elcan,

2

哈斯克尔,145个 143字节

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

1
短一点:import Data.ByteStringplus main=getArgs>>=Data.ByteString.readFile.(!!0)>>=mapM_(printf"%02X ").unpack
nimi

2

Rust,141个字节(贡献版)

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字节(原始版本)

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个字节:TIO
Herman L

2

bash + Stax,6 + 4 + 1 = 11个字节

至此,这是完整的理论工艺。您实际上无法运行此程序。如果一切都按照其规范工作,那将起作用,但还不是一切。

bash脚本是

]<$1

并且stax程序必须编译并保存为]是

╛↕ßú┼_

将您的字符集设置为ISO 8859-1(Windows-1252在这里不起作用)并继续

开箱并解释

_          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

Emojicode186个 162字节

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

在这里在线尝试

取消高尔夫:

📦 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个字节

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

在线尝试!

  • @*ARGS[0] 是第一个命令行参数。
  • .IO将(假定的)文件名转换为IO::Path对象。
  • .slurp(:bin)将整个文件读入Buf字节缓冲区。(没有:bin文件内容将作为Unicode字符串返回。)
  • .list 从缓冲区返回字节值的列表。
  • .fmt('%02X')是一种List方法,该方法使用给定的格式字符串设置列表元素的格式,然后使用空格将它们连接在一起。(方便!)
  • .say 打印该字符串。

根据Python的答案,实际上很可能实现TIO链接
Draco18s不再信任

一些清理可以删除.list41个字节
乔金



1

球拍,144字节

该提交不会输出尾随空格,也不会尾随换行符。让我知道这是否被视为漏洞:)

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

清理了

(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

第四(gforth),71字节

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

在线尝试!

TIO 3 arg位于最后一行,因为TIO在传递代码之前将“ -e bye”传递给命令行解析器

代码说明

: 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个字节

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个字节

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

1

Wolfram语言(Mathematica)94 89字节

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

在线尝试!

由于命令名称很长,因此代码很容易解释。应该从右到左阅读:

$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个字符

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

样品运行:

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 

在线尝试!


1

Pyth,12个字节

jdcr1.Hjb'w2

在线尝试!

将输入作为用户提示(无法访问命令行参数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()

(*)我不是100%确定是否要这样做,但是一个基数256位数字(例如,一个字符)将始终转换为精确的2个十六进制数字,从而无需使用零填充。


1

Node.js,118个字节

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

结果如下所示: 在此处输入图片说明

顺便说一句,test.txt示例中的内容如下:

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

(为什么到底需要大写输出。我不得不在加上转换toUpperCase(),而这需要13个字节。)


0

C# 的.NET框架4.7.2 - 235 213 203 191 175 140个字节

在线尝试!

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
我认为以下内容将节省一些字节(我认为现在为181):使用System.IO; class P {static void Main(string [] a){if(a.Length> 0 && File.Exists(a [0]) ){foreach(File.ReadAllBytes(a [0])中的var b){System.Console.Write($“ {b.ToString(” X2“)}”);}}}}
PmanAce

@PmanAce如果删除某些空格,则降至175。–
facepalm42

0

05AB1E,18个字节

IvyÇh2j' 0.:' Jvy?

在线尝试!

说明:

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