3 people like it.

Even more Fast hex dump

A simple function that nicely formats arrays of bytes. Useful in FSI or logging. byte array -> string seq Inspired by http://fssnip.net/hq, but optimized to become O(n).

 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: 
45: 
46: 
open System.Text

let hexDump bytesPerLine (bytes: byte array) =
    let join (xs: string array) = 
        xs |> Array.fold (fun (acc: StringBuilder) x -> acc.Append x) (StringBuilder())
           |> sprintf "%O"

    seq { for i in 0..bytesPerLine..(bytes.Length - 1) ->
            Array.sub bytes i (min bytesPerLine (bytes.Length - i))
            |> Array.map (sprintf "%02X ")
            |> join
            |> sprintf "%08X  %s" i }


let hexDump1 bytesPerLine (bytes: byte array) =
    let inline join (xs: string array) = 
        System.String.Join(" ", xs)

    seq { for i in 0..bytesPerLine..(bytes.Length - 1) ->
            i.ToString("X08") + " " +
            (Array.sub bytes i (min bytesPerLine (bytes.Length - i))
             |> Array.map (fun b -> b.ToString("X2"))
             |> join) }

[|0uy..100uy|]
|> hexDump1 16
|> Seq.iter (printfn "%s")

// 00000000  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
// 00000010  10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 
// 00000020  20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 
// 00000030  30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 
// 00000040  40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 
// 00000050  50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
// 00000060  60 61 62 63 64 

// C2D T7300, W8 x64, .NET 4.5
// benchmark: Real: 00:00:09.061, CPU: 00:00:08.502, GC gen0: 578, gen1: 1, gen2: 1
Array.zeroCreate 1000000
|> hexDump 16
|> Seq.iter ignore

// benchmark1: Real: 00:00:00.255, CPU: 00:00:00.265, GC gen0: 32, gen1: 0, gen2: 0
Array.zeroCreate 1000000
|> hexDump1 16
|> Seq.iter ignore
namespace System
namespace System.Text
val hexDump : bytesPerLine:int -> bytes:byte array -> seq<string>

Full name: Script.hexDump
val bytesPerLine : int
val bytes : byte array
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
type 'T array = 'T []

Full name: Microsoft.FSharp.Core.array<_>
val join : (string array -> string)
val xs : string array
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
module Array

from Microsoft.FSharp.Collections
val fold : folder:('State -> 'T -> 'State) -> state:'State -> array:'T [] -> 'State

Full name: Microsoft.FSharp.Collections.Array.fold
val acc : StringBuilder
Multiple items
type StringBuilder =
  new : unit -> StringBuilder + 5 overloads
  member Append : value:string -> StringBuilder + 18 overloads
  member AppendFormat : format:string * arg0:obj -> StringBuilder + 4 overloads
  member AppendLine : unit -> StringBuilder + 1 overload
  member Capacity : int with get, set
  member Chars : int -> char with get, set
  member Clear : unit -> StringBuilder
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EnsureCapacity : capacity:int -> int
  member Equals : sb:StringBuilder -> bool
  ...

Full name: System.Text.StringBuilder

--------------------
StringBuilder() : unit
StringBuilder(capacity: int) : unit
StringBuilder(value: string) : unit
StringBuilder(value: string, capacity: int) : unit
StringBuilder(capacity: int, maxCapacity: int) : unit
StringBuilder(value: string, startIndex: int, length: int, capacity: int) : unit
val x : string
StringBuilder.Append(value: char []) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: obj) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: uint64) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: uint32) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: uint16) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: decimal) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: float) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: float32) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: int64) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: int) : StringBuilder
   (+0 other overloads)
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
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 sub : array:'T [] -> startIndex:int -> count:int -> 'T []

Full name: Microsoft.FSharp.Collections.Array.sub
val min : e1:'T -> e2:'T -> 'T (requires comparison)

Full name: Microsoft.FSharp.Core.Operators.min
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.map
val hexDump1 : bytesPerLine:int -> bytes:byte array -> seq<string>

Full name: Script.hexDump1
Multiple items
type String =
  new : value:char -> string + 7 overloads
  member Chars : int -> char
  member Clone : unit -> obj
  member CompareTo : value:obj -> int + 1 overload
  member Contains : value:string -> bool
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EndsWith : value:string -> bool + 2 overloads
  member Equals : obj:obj -> bool + 2 overloads
  member GetEnumerator : unit -> CharEnumerator
  member GetHashCode : unit -> int
  ...

Full name: System.String

--------------------
System.String(value: nativeptr<char>) : unit
System.String(value: nativeptr<sbyte>) : unit
System.String(value: char []) : unit
System.String(c: char, count: int) : unit
System.String(value: nativeptr<char>, startIndex: int, length: int) : unit
System.String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
System.String(value: char [], startIndex: int, length: int) : unit
System.String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Encoding) : unit
System.String.Join(separator: string, values: System.Collections.Generic.IEnumerable<string>) : string
System.String.Join<'T>(separator: string, values: System.Collections.Generic.IEnumerable<'T>) : string
System.String.Join(separator: string, [<System.ParamArray>] values: obj []) : string
System.String.Join(separator: string, [<System.ParamArray>] value: string []) : string
System.String.Join(separator: string, value: string [], startIndex: int, count: int) : string
System.Int32.ToString() : string
System.Int32.ToString(provider: System.IFormatProvider) : string
System.Int32.ToString(format: string) : string
System.Int32.ToString(format: string, provider: System.IFormatProvider) : string
val b : byte
System.Byte.ToString() : string
System.Byte.ToString(provider: System.IFormatProvider) : string
System.Byte.ToString(format: string) : string
System.Byte.ToString(format: string, provider: System.IFormatProvider) : string
module Seq

from Microsoft.FSharp.Collections
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val zeroCreate : count:int -> 'T []

Full name: Microsoft.FSharp.Collections.Array.zeroCreate
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore

More information

Link:http://fssnip.net/ht
Posted:4 years ago
Author:Vasily Kirichenko
Tags: hex dump , hex , sequences , conversion