2 people like it.
Like the snippet!
hexdump (somewhat fast)
Simple functions to display a hex dump of a byte array using sequence expressions, with ASCII. Rewrote naive version that used string concat, based on optimizations in http://fssnip.net/ht, and cleaned up ASCII formatting.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
|
// Without ASCII column.
let hexdump w (b : byte[]) =
seq {
for i in 0..w..b.Length - 1 ->
let hex =
Seq.skip i b
|> Seq.truncate w
|> Seq.map (sprintf "%02X ")
|> Seq.fold ( + ) ""
sprintf "%08X %s\n" i hex
}
|> Seq.iter (printf "%s")
(Formatting helper functions omitted.)
// With ASCII column.
let hexdump' w (b : byte[]) =
seq {
for i in 0..w..b.Length - 1 ->
let byt = Seq.skip i b
|> Seq.truncate w
let hex = Seq.map (sprintf "%02X ") byt
|> Seq.fold ( + ) ""
|> pad w
let asc = Seq.map (fun c -> sprintf "%c" (filterChar c)) byt
|> Seq.fold ( + ) ""
sprintf "%08X %s %s\n" i hex asc
}
|> Seq.iter (printf "%s")
// Example output in FSI:
//> hexdump 16 someBytes;;
//00000000 92 36 81 DC 1F F0 87 1F 49 93 8F D3 6C 31 22 71
//00000010 4F 2E BE C5 8D 5D D1 E6 0F 6A 2B D5 4A 8C 53 B7
//00000020 01 69 E7
//val it : unit = ()
//
//> hexdump' 16 someBytes;;
//00000000 49 AA 22 B2 F5 19 FC 48 C5 F9 1F 96 3C C7 53 C8 I."....H....<.S.
//00000010 75 4E 1E 3B 1F 6E CD 68 AB F6 63 FC 80 25 55 A5 uN.;.n.h..c..%U.
//00000020 6C F3 8E 2E FB E3 A4 D3 21 E7 EE 50 0B 1F 9C l.......!..P...
//val it : unit = ()
|
val hexdump : w:int -> b:byte [] -> unit
Full name: Script.hexdump
val w : int
val b : byte []
Multiple items
val byte : value:'T -> byte (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.byte
--------------------
type byte = System.Byte
Full name: Microsoft.FSharp.Core.byte
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val i : int
property System.Array.Length: int
val hex : string
module Seq
from Microsoft.FSharp.Collections
val skip : count:int -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.skip
val truncate : count:int -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.truncate
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
val sprintf : format:Printf.StringFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val fold : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State
Full name: Microsoft.FSharp.Collections.Seq.fold
val iter : action:('T -> unit) -> source:seq<'T> -> unit
Full name: Microsoft.FSharp.Collections.Seq.iter
val printf : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printf
// Filters non-printable characters.
let filterChar (b : byte) = if int b <= 32 || int b > 127 then '.' else char b
// Pads a string based on number (w) of bytes to display.
let pad w (s : string) =
let t = (w * 2) + w
if s.Length < t then s + String.replicate (t - s.Length) " " else s
val hexdump' : w:int -> b:byte [] -> unit
Full name: Script.hexdump'
val byt : seq<byte>
val pad : w:int -> s:string -> string
Full name: Script.pad
val asc : string
val c : byte
val filterChar : b:byte -> char
Full name: Script.filterChar
More information