โปรแกรมทุ่มตลาด hex สั้นที่สุด


13

ท้าทาย

สร้างโปรแกรมคอนโซลเพื่อแสดงแต่ละไบต์ของไฟล์


การชนะ

เนื่องจากนี่คือจึงมีจำนวนไบต์น้อยที่สุดที่ชนะ


กฎระเบียบ

  • โปรแกรมจะต้องเป็นแอปพลิเคชันคอนโซลซึ่งหมายความว่ามันจะถูกเรียกใช้จากล่ามบรรทัดคำสั่งบางประเภท
  • ทุกไบต์ต้องเป็นตัวพิมพ์ใหญ่เป็นเลขฐานสิบหกซึ่งคั่นด้วยช่องว่างและต้องเป็น 2 หลัก (ใส่หมายเลข 0 ก่อนถ้ามี 1 หลัก)
  • ไฟล์จะต้องอ่านโดยใช้ 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 เพื่อหลีกเลี่ยง facepalms ฉันขอแนะนำให้ใช้Sandboxเพื่อช่วยคุณออกแบบความท้าทายในอนาคตก่อนโพสต์
อดัม

2
เป็นไปได้อย่างไรที่จะแสดงค่าไบต์ทั้งหมดในครั้งเดียวหากมันไม่พอดีกับหน้าจอ การเลื่อนไม่ชัดเจน "พร้อมกัน" นอกจากนี้มีอะไรผิดปกติ (ฟังก์ชั่น) เพียงแค่คืนค่าหรือไม่
อดัม

7
@ facepalm42 โปรดอย่าเปลี่ยนสเป็คเป็นเวลานานหลังจากโพสต์ความท้าทาย โพสต์ต้นฉบับไม่ได้ระบุรูปแบบที่แน่นอนของตัวเลขฐานสิบหกทำให้เหลือผู้ตอบที่ถูกต้อง การแก้ไขล่าสุดของคุณทำให้คำตอบปัจจุบันของฉันไม่ถูกต้อง!
อดัม

11
มีเหตุผลบางอย่างที่คุณอนุญาตให้ใช้อาร์กิวเมนต์บรรทัดคำสั่งหรือพร้อมท์ผู้ใช้หรือไม่ เกิดอะไรขึ้นกับการใช้ชื่อไฟล์เป็นอาร์กิวเมนต์ของฟังก์ชัน
อดัม

3
มันจะมีประโยชน์หากคุณมีhello.txtไฟล์ข้อความอย่างง่ายเป็นตัวอย่างสำหรับอินพุตและสิ่งที่ควรเป็นเอาท์พุท ตัวอย่างเช่นถ้าhello.txtมีเพียงคำที่helloมีตัวแบ่งบรรทัดสิ่งนี้จะแสดงในผลลัพธ์ได้อย่างไร คุณจัดกลุ่มไบต์เป็นคำแบบ 16 บิต, 32- บิตหรือ 64- บิต? หรือแต่ละไบต์แสดงเป็นเลขฐานสิบหกสองหลัก? ช่องว่างยอมรับได้หลังจากแต่ละไบต์เป็นเลขฐานสิบหกหรือหลังคำ x-bit แต่ละคำ? คุณต้องการการ0xแก้ไขล่วงหน้าสำหรับแต่ละไบต์หรือไม่
Shaun Bebbers

คำตอบ:



6

ทับทิมขนาด 26 ไบต์

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

ลองออนไลน์!


สิ่งนี้อ่านเนื้อหาของไฟล์ที่กำหนดเส้นทางไฟล์เป็นอาร์กิวเมนต์ของโปรแกรมหรือไม่ จาก TIO ดูเหมือนว่าจะอ่านจาก STDIN แต่ฉันไม่รู้ว่า Ruby ดีพอที่จะบอกว่ามันไม่ถูกต้อง
Kevin Cruijssen

1
@KevinCruijssen ใช่มันใช้พา ธ ของไฟล์เป็นอาร์กิวเมนต์ของโปรแกรม หากไม่มีข้อโต้แย้งให้$<เปลี่ยนเป็นการอ่านจาก STDIN แทน
Value Ink


6

Java 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.tioเป็นไฟล์อาร์กิวเมนต์พา ธ ซึ่งจะมีอินพุตที่กำหนดเป็นเนื้อหาไฟล์

คำอธิบาย:

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 หลักจะต้องเป็นสาธารณะวิธีการอินเตอร์เฟซที่เป็นสาธารณะเสมอinterfaceสั้นกว่า+class public
Grimmy

3
ด้วย Java 11 คุณสามารถใช้Path.ofแทนPaths.get
Holger

1
@ Holger ขอบคุณ! :)
Kevin Cruijssen

2
@Grimy ตั้งแต่ Java 9 วิธีการอินเตอร์เฟซที่ไม่ได้เสมอpublicแต่พวกเขาจะเว้นแต่ประกาศอย่างชัดเจนpublic private
Holger

6

PHP , 60 59 54 ไบต์

<?=wordwrap(bin2hex(implode(file($argv[1]))),2,' ',1);
  • -1 ไบต์ขอบคุณ manassehkatz
  • -5 ไบต์ขอบคุณ Blackhole

ลองออนไลน์!


1
ควรจะสามารถทิ้งส่วนท้าย?>และบันทึก 2 ไบต์หรือถ้าไม่ได้ผลให้แทนที่?>ด้วยเครื่องหมายอัฒภาคและบันทึก 1 ไบต์
manassehkatz-Moving 2 Codidact

2
ใช้implode(file($x))แทนfile_get_contents($x)(-4 ไบต์)
Blackhole

2
และwordwrap()ด้วยความเป็นพารามิเตอร์ที่ผ่านมาเป็นหนึ่งไบต์สั้นกว่า1 chunk_split()
Blackhole


4

APL (Dyalog Unicode)ขนาด 16 ไบต์

ฟังก์ชันนำหน้าเงียบโดยไม่ระบุชื่อ ส่งคืน (และพิมพ์โดยนัยหากไม่ได้ใช้ค่าอื่น) เมทริกซ์สองแถวที่มีบิตสูงสุด 4 บิตแสดงเป็นเลขทศนิยม 0–15 ในแถวบนสุดและ 4 บิตล่างแทนในแถวล่าง นั่นคือเมทริกซ์มีคอลัมน์ได้มากเท่ากับไฟล์ที่มีไบต์

16 1683 ¯1∘⎕MAP

ลองออนไลน์!

⎕MAP แม็พชื่อไฟล์อาร์กิวเมนต์ไปยังอาร์เรย์
 ด้วยพารามิเตอร์:
¯1 ความยาวทั้งหมดของไฟล์
83 อ่านเป็นจำนวนเต็ม 8 บิต

16 16⊤ แปลง (anti-base) เป็นเลขฐานสิบหก 2 ตำแหน่ง


1
@ facepalm42 มันเป็นเลขฐานสิบหก เช่นH72 คือ 4 ×16¹ + 8 ×16⁰หรือ [4,8] ₁₆ [4,8]ดังนั้นคอลัมน์แรกในตัวอย่างอ่าน
ADAM

โอ้ฉันลืมไปแล้ว! ขอโทษ
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)แทนที่จะหั่นเอาต์พุตของ hex
Mostly Harmless

@ MostlyHarmless Done! -11 ไบต์ ขอบคุณ!
mprogrammer

แล้ว '% 02X' แทนที่จะเป็น '% 02x' แล้วกำจัด.upper()
ประธานาธิบดี James Moveon Polk

คุณสามารถบันทึกไบต์จากการimport sysใช้raw_input()เป็นชื่อไฟล์แทน กฎอนุญาตให้ผู้ใช้แจ้ง
บลู

@Blue ขอบคุณ! และมันก็ยิ่งสั้นลงใน Python 3 ซึ่งคุณสามารถทำได้input()
mprogrammer

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 \ ลดไมเนอร์:
จัดการ

ขอบคุณความคิดใด ๆ ที่จะได้รับ\nและ\ ทำงานในรุ่นลิงก์นี้คืออะไร แก้ไข: ฉันเพิ่มอักขระหลบหนีอื่น
โจนาธานอัลลัน

หากฉันเข้าใจคุณอย่างถูกต้องคุณเพียงต้องการเปลี่ยนจากคำพูดสองคำเป็นคำพูดเดี่ยว: ลองออนไลน์!
จัดการ

ยอดเยี่ยมขอบคุณ!
Jonathan Allan

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

3

Kotlin , 130 127 104 93 92 ไบต์

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

ลองออนไลน์!

แก้ไข: -11 ไบต์ขอบคุณ @ChrisParton

แก้ไข: Working TIO

แก้ไข: -1 ไบต์ขอบคุณ @KevinCruijssen


1
คุณสามารถลดการนำเข้าและการอ้างอิงFileเป็นjava.io.Fileแทนได้หรือไม่
Chris Parton

@ ChrisParton ถูกต้องแล้วขอบคุณ!
Quinn

นี่คือ TIO ที่ใช้งานได้ คุณสามารถใช้./.input.tioเป็นอาร์กิวเมนต์เส้นทางไฟล์และมันจะใช้ STDIN เป็นเนื้อหาไฟล์ :)
Kevin Cruijssen

@KevinCruijssen ขอบคุณ! เพิ่งปรับปรุงคำตอบ
Quinn

1
ฉันไม่รู้จัก Kotlin แต่ TIO ยังใช้งานได้ถ้าฉันเอาที่ว่างa:Arrayออกดังนั้นฉันคิดว่าคุณสามารถบันทึกไบต์ได้
Kevin Cruijssen

2

Dart , 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

Haskell, 145 143 ไบต์

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

1
นิด ๆ หน่อย ๆ สั้น: บวกimport Data.ByteString main=getArgs>>=Data.ByteString.readFile.(!!0)>>=mapM_(printf"%02X ").unpack
nimi

2

สนิมขนาด 141 ไบต์ (รุ่นที่สนับสนุน)

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

สนิม, 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 ไบต์

นี่คือยานทฤษฎีที่สมบูรณ์ในตอนนี้ คุณไม่สามารถเรียกใช้สิ่งนี้ได้ หากทุกอย่างทำงานตามสเป็คมันจะใช้ได้ แต่ก็ยังไม่พอ

สคริปต์ทุบตีคือ

]<$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

อิโมจิโคด , 186 162 ไบต์

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

ลองออนไลน์ได้ที่นี่

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

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นั้นเป็นไปได้จริง
Draco18 ไม่ไว้วางใจ SE

บางจัดเรียงสามารถลบ.listสำหรับ41 ไบต์
โจกษัตริย์


1

Python 3, 75 ไบต์

ส่วนใหญ่เป็นสำเนาของคำตอบหลามของ Maxwell

import sys
print(' '.join('%02X'%b for b in open(sys.argv[1],'rb').read()))

sys.argv[1]คุณหมายถึงอาจจะ ด้วยsys.argv[0]สคริปต์นี้ทำงานเหมือน quine ;-)
anion

@ สหาย: โอ๊ะโอฮ่าฮ่าซ่อม ...
ประธานาธิบดีเจมส์ Moveon Polk

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

ภาษา 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

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` `)

ผลลัพธ์ที่ได้จะเป็นอย่างไร: ป้อนคำอธิบายรูปภาพที่นี่

Btw เนื้อหาของtest.txtในตัวอย่างเป็นดังนี้:

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

(เพราะเหตุใดในโลกจึงจำเป็นต้องใช้ตัวพิมพ์ใหญ่ฉันต้องเพิ่มการแปลงด้วยtoUpperCase()และมีค่าใช้จ่าย 13 ไบต์)


0

C # .NET Framework 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 {โมฆะคงที่หลัก (สตริง [] a) {ถ้า (a.Length> 0 && File.Exists (a [0]) ) {foreach (var b ใน File.ReadAllBytes (a [0])) {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?
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.