Racket/Hexdump
Från Täpp-Anders
Hoppa till navigeringHoppa till sök
#lang racket
;;;;;
;; Hexdump implementerad i Racket
;; Täpp-Anders Sikvall 2026-04-03 anders@sikvall.se
;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SYNOPSIS
;; racket hexdump.rkt [ OPTIONS ] filename
;;
;; OPTIONS
;; -h Gives a short help text to the utility
;; --bytes-per-line, -n Determines how many bytes are decoded per line (default 16)
;; --hex, -x Show only hex dump
;; --ascii, -a Show only ASCII dump
(require racket/cmdline)
(define (hexdump-file filename
#:only-hex? [only-hex? #f]
#:only-ascii? [only-ascii? #f]
#:bytes-per-line [n 16])
(printf "Läser fil: ~a (~a bytes)\n\n" filename (file-size filename))
(call-with-input-file filename
(λ (in)
(let loop ([offset 0])
(define chunk (read-bytes n in))
(cond
[(eof-object? chunk) (void)]
[(bytes? chunk)
(define len (bytes-length chunk))
(printf "~a " (~r offset #:base 16 #:min-width 8 #:pad-string "0"))
(define show-both? (not (xor only-hex? only-ascii?)))
(cond
[(and only-hex? (not show-both?))
(for ([i (in-range n)])
(printf "~a " (if (< i len)
(~r (bytes-ref chunk i) #:base 16 #:min-width 2 #:pad-string "0")
" "))
(when (and (= (modulo (add1 i) 8) 0) (< i (sub1 n)))
(display " ")))
(newline)]
[(and only-ascii? (not show-both?))
(display " |")
(for ([b (in-bytes chunk)]) (display (if (and (>= b 32) (<= b 126)) (integer->char b) ".")))
(for ([_ (in-range (- n len))]) (display " "))
(display "|\n")]
[else ; båda eller ingen flagga
(for ([i (in-range n)])
(printf "~a " (if (< i len)
(~r (bytes-ref chunk i) #:base 16 #:min-width 2 #:pad-string "0")
" "))
(when (and (= (modulo (add1 i) 8) 0) (< i (sub1 n)))
(display " ")))
(display "|")
(for ([b (in-bytes chunk)]) (display (if (and (>= b 32) (<= b 126)) (integer->char b) ".")))
(for ([_ (in-range (- n len))]) (display " "))
(display "|\n")])
(loop (+ offset n))])))))
(define-values (filename only-hex? only-ascii? bytes-per-line)
(let ([only-hex? #f] [only-ascii? #f] [bytes-per-line 16])
(command-line
#:program "hexdump"
#:usage-help "Användning: racket hexdump.rkt [alternativ] <fil>"
#:once-each
[("-x" "--hex") "Visa endast hex-delen" (set! only-hex? #t)]
[("-a" "--ascii") "Visa endast ASCII-delen" (set! only-ascii? #t)]
[("-n" "--bytes-per-line") n
"Antal bytes per rad (standard: 16)" (let ([num (string->number n)]) (when num (set! bytes-per-line num)))]
#:args (filename)
(values filename only-hex? only-ascii? bytes-per-line))))
(if (not (file-exists? filename))
(printf "Fel: Filen \"~a\" finns inte.\n" filename)
(hexdump-file filename
#:only-hex? only-hex?
#:only-ascii? only-ascii?
#:bytes-per-line bytes-per-line))