crackNum: Crack various integer and floating-point data formats

[ bsd3, program, tools ] [ Propose Tags ] [ Report a vulnerability ]

Crack IEEE-754 and other float formats and arbitrary sized words and integers, showing the layout.

For details, please see: http://github.com/LeventErkok/crackNum/


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14, 3.15, 3.16, 3.17, 3.18, 3.19, 3.20, 3.21, 3.22, 3.23, 3.24, 3.25, 3.26, 3.27, 3.28, 3.29, 3.30 (info)
Change log CHANGES.md
Dependencies base (>=4.11 && <5), deepseq, directory, filepath, ghc, libBF, process, sbv (>=11.0), tasty, tasty-golden [details]
License BSD-3-Clause
Copyright Levent Erkok
Author Levent Erkok
Maintainer erkokl@gmail.com
Uploaded by LeventErkok at 2026-08-20T21:12:00Z
Category Tools
Home page http://github.com/LeventErkok/CrackNum
Source repo head: git clone https://github.com/LeventErkok/crackNum.git
Distributions Arch:3.6, LTSHaskell:3.15, Stackage:3.25
Reverse Dependencies 2 direct, 35 indirect [details]
Executables crackNum
Downloads 18665 total (83 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs not available [build log]
Last success reported on 2026-08-20 [all 1 reports]

Readme for crackNum-3.27

[back to package description]

Decode/Encode Integers, Words, and IEEE754 and other float formats

On Hackage: http://hackage.haskell.org/package/crackNum

crackNum shows you exactly how a number is laid out in memory: the bit pattern, its fields, the classification, and the value in binary, octal, decimal, and hex. It works in both directions:

  • Encoding: give it a value (2.5, -2.3e6, NaN, 0x3.2p5), and it shows the bit-pattern it turns into, together with the rounding that took place.
  • Decoding: give it a bit-pattern (0xdeadbeef, 0b0110, 32'hfdc71fc6), and it shows the value it stands for.

Installation

Prebuilt binaries (nothing to build, no Haskell toolchain)

The easiest way to get crackNum is from the Releases page. Each bundle is self-contained: the crackNum executable, a copy of z3, the graphical interface, a LICENSE, and a README with the platform-specific details.

Platform Asset Notes
Linux (x86_64) crackNum-<version>-linux-x86_64.tar.gz Statically linked, so there is no glibc or distribution requirement: it runs as-is on any x86_64 Linux, old or new.
macOS (Apple Silicon) crackNum-<version>-macos-arm64.tar.gz Includes CrackNum.app. Ad-hoc signed rather than notarized, so clear the quarantine flag as the bundled README explains.

Unpack it and you can run straight out of the directory:

$ tar xzf crackNum-3.27-linux-x86_64.tar.gz
$ cd crackNum-3.27-linux-x86_64
$ ./crackNum -fsp 3.5

To use it from anywhere, put the files on your PATH. z3 has to be there too, since crackNum shells out to it for every operation:

$ mkdir -p ~/bin && cp crackNum z3 ~/bin/       # on Linux, add crackNum.tcl for the GUI
$ export PATH=$HOME/bin:$PATH                   # add to your shell rc to make it stick

Each bundle's own README covers the platform details — installing CrackNum.app on macOS, and wish for the Tcl/Tk GUI on Linux.

From Hackage

$ cabal install crackNum

crackNum uses SBV and delegates the actual floating-point reasoning to an SMT solver, so installed this way you also need z3 on your PATH. (The prebuilt bundles above carry their own copy, so there is nothing extra to install.)

Supported formats

Flag        Format                               Exponent   Significand
-----------------------------------------------------------------------
-fhp        Half precision (IEEE-754 binary16)          5            11
-fbp        Brain float (bfloat16)                      8             8
-ftf32      TensorFloat-32                              8            11
-fsp        Single precision (binary32)                 8            24
-fdp        Double precision (binary64)                11            53
-fqp        Quad precision (binary128)                 15           113
-fe5m2      FP8, IEEE-754 style                         5             3
-fe4m3      FP8, alternate (no infinities)              4             4
-ffp4       FP4 (E2M1)                                  2             2
-ffp4e0m3   FP4 (E0M3), sign-magnitude                  0             3
-fa+b       Arbitrary IEEE-754 float                    a             b

Significand sizes include the implicit bit.

FP4 (E0M3) is the odd one out: with no exponent bits at all it is really a 4-bit sign-magnitude integer, holding a sign and a 3-bit magnitude. It covers -7 to 7, with both a positive and a negative zero, and has neither NaN nor Inf.

Integers come in two flavors: -iN for a signed N-bit 2's complement integer, and -wN for an unsigned N-bit word. Both N and the arbitrary float sizes can be as large as you like, within machine-word limits.

Note that TF32 is cracked as its 19 architectural bits; hardware typically carries these in a 32-bit container with the remaining bits unused.

Rounding mode is selected with -r, and defaults to RNE if not given: RNE (nearest, ties to even), RNA (nearest, ties away), RTP (towards positive infinity), RTN (towards negative infinity), and RTZ (towards zero).

Example: Encode a decimal number as a single-precision IEEE754 number

$ crackNum -fsp -- -2.3e6
Satisfiable. Model:
  ENCODED = -2300000.0 :: Float
                  3  2          1         0
                  1 09876543 21098765432109876543210
                  S ---E8--- ----------S23----------
   Binary layout: 1 10010100 00011000110000110000000
      Hex layout: CA0C 6180
       Precision: Single
            Sign: Negative
        Exponent: 21 (Stored: 148, Bias: 127)
  Classification: FP_NORMAL
          Binary: -0b1.0001100011000011p+21
           Octal: -0o1.061414p+21
         Decimal: -2300000.0
             Hex: -0x2.3186p+20
   Rounding mode: RNE: Round nearest ties to even.
            Note: Conversion from "-2.3e6" was exact. No rounding happened.

Example: Encode with a different rounding mode

$ crackNum -fsp 1.3 -rRTZ
Satisfiable. Model:
  ENCODED = 1.3 :: Float
                  3  2          1         0
                  1 09876543 21098765432109876543210
                  S ---E8--- ----------S23----------
   Binary layout: 0 01111111 01001100110011001100110
      Hex layout: 3FA6 6666
       Precision: Single
            Sign: Positive
        Exponent: 0 (Stored: 127, Bias: 127)
  Classification: FP_NORMAL
          Binary: 0b1.0100110011001100110011
           Octal: 0o1.23146314
         Decimal: 1.3
             Hex: 0x1.4ccccc
   Rounding mode: RTZ: Round towards zero.
            Note: Conversion from "1.3" was not faithful. Status: Inexact.

Example: Decode a single-precision IEEE754 number float from memory-layout

$ crackNum -fsp  0xfc00 abc1
Satisfiable. Model:
  DECODED = -2.6723903e36 :: Float
                  3  2          1         0
                  1 09876543 21098765432109876543210
                  S ---E8--- ----------S23----------
   Binary layout: 1 11111000 00000001010101111000001
      Hex layout: FC00 ABC1
       Precision: Single
            Sign: Negative
        Exponent: 121 (Stored: 248, Bias: 127)
  Classification: FP_NORMAL
          Binary: -0b1.00000001010101111000001p+121
           Octal: -0o2.00527404p+120
         Decimal: -2.6723903e36
             Hex: -0x2.02af04p+120

Example: Encode as an E4M3 FP8 float

$ crackNum -fe4m3 2.5
Satisfiable. Model:
  ENCODED = 2.5 :: E4M3
                  7 6543 210
                  S -E4- S3-
   Binary layout: 0 1000 010
      Hex layout: 42
       Precision: 4 exponent bits, 3 significand bits
            Sign: Positive
        Exponent: 1 (Stored: 8, Bias: 7)
  Classification: FP_NORMAL
          Binary: 0b1.01p1
           Octal: 0o2.4
         Decimal: 2.5
             Hex: 0x2.8

Example: Decode an FP4 (E2M1) float

$ crackNum -ffp4 0b0111
Satisfiable. Model:
  DECODED = 6.0 :: FP4
                  3 21 0
                  S E2 S
   Binary layout: 0 11 1
      Hex layout: 7
       Precision: 2 exponent bits, 1 significand bit
            Sign: Positive
        Exponent: 2 (Stored: 3, Bias: 1)
  Classification: FP_NORMAL
          Binary: 0b1.1p+2
           Octal: 0o6
         Decimal: 6.0
             Hex: 0x6

Example: Decode an FP4 (E0M3) sign-magnitude integer

$ crackNum -ffp4e0m3 0b1101
Satisfiable. Model:
  DECODED = -5 :: FP4E0M3
                  3 210
                  S -M-
   Binary layout: 1 101
      Hex layout: D
            Type: 4-bit sign-magnitude integer
            Sign: Negative
          Binary: -0b101
           Octal: -0o5
         Decimal: -5
             Hex: -0x5

Example: Encode an FP4 (E0M3) sign-magnitude integer

$ crackNum -ffp4e0m3 -- -5
Satisfiable. Model:
  ENCODED = -5 :: FP4E0M3
                  3 210
                  S -M-
   Binary layout: 1 101
      Hex layout: D
            Type: 4-bit sign-magnitude integer
            Sign: Negative
          Binary: -0b101
           Octal: -0o5
         Decimal: -5
             Hex: -0x5
   Rounding mode: RNE: Round nearest ties to even.
            Note: Conversion from "-5" was exact. No rounding happened.

Example: Encode a TensorFloat-32 number

$ crackNum -ftf32 2.5
Satisfiable. Model:
  ENCODED = 2.5 :: FloatingPoint 8 11
                  1          0
                  8 76543210 9876543210
                  S ---E8--- ---S10----
   Binary layout: 0 10000000 0100000000
      Hex layout: 2 0100
       Precision: 8 exponent bits, 10 significand bits
            Sign: Positive
        Exponent: 1 (Stored: 128, Bias: 127)
  Classification: FP_NORMAL
          Binary: 0b1.01p1
           Octal: 0o2.4
         Decimal: 2.5
             Hex: 0x2.8
   Rounding mode: RNE: Round nearest ties to even.
            Note: Conversion from "2.5" was exact. No rounding happened.

Example: Decode a custom (2+3) float from memory-layout

$ crackNum -f2+3 0b10011
Satisfiable. Model:
  DECODED = -0.75 :: FloatingPoint 2 3
                  4 32 10
                  S E2 S2
   Binary layout: 1 00 11
      Hex layout: 13
       Precision: 2 exponent bits, 2 significand bits
            Sign: Negative
        Exponent: 0 (Subnormal, with fixed exponent value. Stored: 0, Bias: 1)
  Classification: FP_SUBNORMAL
          Binary: -0b1.1p-1
           Octal: -0o6p-3
         Decimal: -0.75
             Hex: -0xcp-4

Example: Encode an integer as a 7-bit signed word

$ crackNum -i7 12
Satisfiable. Model:
  ENCODED = 12 :: IntN 7
                  654 3210
   Binary layout: 000 1100
      Hex layout: 0C
            Type: Signed 7-bit 2's complement integer
            Sign: Positive
          Binary: 0b1100
           Octal: 0o14
         Decimal: 12
             Hex: 0xc

Example: Decode a 4-bit unsigned word

$ crackNum -w4 0xE
Satisfiable. Model:
  DECODED = 14 :: WordN 4
                  3210
   Binary layout: 1110
      Hex layout: E
            Type: Unsigned 4-bit word
          Binary: 0b1110
           Octal: 0o16
         Decimal: 14
             Hex: 0xe

Example: Decode two half-precision floats in two lanes

$ crackNum -l2 -fhp 32\'hfdc71fc6
== Lane 1 ============================================================
Satisfiable. Model:
  DECODED = NaN :: FloatingPoint 5 11
                  1       0
                  5 43210 9876543210
                  S -E5-- ---S10----
   Binary layout: 1 11111 0111000111
      Hex layout: FDC7
       Precision: Half (5 exponent bits, 10 significand bits.)
            Sign: Negative
        Exponent: 16 (Stored: 31, Bias: 15)
  Classification: FP_NAN (Signaling)
           Value: NaN
            Note: Representation for NaN's is not unique
== Lane 0 ============================================================
Satisfiable. Model:
  DECODED = 0.0075912476 :: FloatingPoint 5 11
                  1       0
                  5 43210 9876543210
                  S -E5-- ---S10----
   Binary layout: 0 00111 1111000110
      Hex layout: 1FC6
       Precision: Half (5 exponent bits, 10 significand bits.)
            Sign: Positive
        Exponent: -8 (Stored: 7, Bias: 15)
  Classification: FP_NORMAL
          Binary: 0b1.111100011p-8
           Octal: 0o3.706p-9
         Decimal: 0.0075912476
             Hex: 0x1.f18p-8

If you use the verilog notation (N'h...), the number of lanes is inferred from the width, so -l is optional in that case.

Graphical interface (optional)

Optionally, crackNum comes with a GUI: pick a format on the left, type a value, and see the encoding/decoding in detail. It is entirely optional — crackNum is fully functional as a command-line tool without it. The GUI is just a thin front-end that calls the crackNum binary underneath, so it supports exactly the same formats.

crackNum GUI

If you installed from a release bundle the GUI is already in it, and there is nothing to build on either platform. The rest of this section is for installing from Hackage or from a source checkout.

macOS — a native Swift/AppKit app (GUI/swiftGUI/). It is not part of the Hackage package, so building it yourself needs a clone of the repository and the Swift compiler that comes with the Xcode Command Line Tools (xcode-select --install):

$ git clone https://github.com/LeventErkok/crackNum.git
$ cd crackNum/GUI/swiftGUI
$ make install      # builds CrackNum.app and copies it into /Applications

Linux — a Tcl/Tk script (GUI/tclGUI/crackNum.tcl). The script ships with the package and is installed alongside the binary, so there is nothing to build; you only need wish (Tk 8.6+):

$ nix profile install nixpkgs#tk   # or: sudo apt install tk / sudo dnf install tk

Then crackNum --gui just works. If you want to run a modified copy of the script, either put it on your PATH as crackNum.tcl, or point at it directly with CRACKNUM_TCL=/path/to/crackNum.tcl.

On both platforms, launch the GUI from the command line via the --gui option, which forwards any format/rounding flags and value to the app:

$ crackNum --gui                 -- open the graphical interface
$ crackNum --gui -fsp 2.5        -- open it with single-precision selected, and 2.5 cracked
$ crackNum --gui 0xdeadbeef      -- open it pre-filled with a value to decode

Bad flags are diagnosed before the GUI comes up: crackNum -ft32 4 --gui reports the unknown format instead of opening an empty window.

Usage info

Usage: crackNum value OR binary/hex-pattern
  -i N                      Signed   integer of N-bits
  -w N                      Unsigned integer of N-bits
  -f fp                     Floating point format fp
  -r rm                     Rounding mode to use. If not given, Nearest-ties-to-Even.
  -l lanes                  Number of lanes to decode
  -h, -?    --help          print help, with examples
  -v        --version       print version info
  -d        --debug         debug mode, developers only
            --gui           launch the graphical interface
            --list-formats  list the formats supported by -f, one per line

Supported floating-point formats (for use with -f):

       hp: Half float             ( 5 +  11)
       bp: Brain float            ( 8 +   8)
     tf32: TensorFloat-32         ( 8 +  11)
       sp: Single precision       ( 8 +  24)
       dp: Double precision       (11 +  53)
       qp: Quad   precision       (15 + 113)
      a+b: Arbitrary IEEE-754     ( a +   b)
     e5m2: FP8 format (IEEE-754)  ( 5 +   3)
     e4m3: FP8 format (Alternate) ( 4 +   4)
      fp4: FP4 format (E2M1)      ( 2 +   2)
  fp4e0m3: FP4 format (E0M3)      ( 0 +   3)

Examples:
 Encoding:
   crackNum -i4       -- -2                   -- encode as 4-bit signed integer
   crackNum -w4       2                       -- encode as 4-bit unsigned integer
   crackNum -f3+4     2.5                     -- encode as float with 3 bits exponent, 4 bits significand
   crackNum -f3+4     2.5 -rRTZ               -- encode as above, but use RTZ rounding mode.
   crackNum -fbp      2.5                     -- encode as a brain-precision float
   crackNum -ftf32    2.5                     -- encode as a TensorFloat-32 float
   crackNum -fdp      2.5                     -- encode as a double-precision float
   crackNum -fqp      2.5                     -- encode as a quad-precision float
   crackNum -fe4m3    2.5                     -- encode as an E4M3 FP8 float
   crackNum -fe5m2    2.5                     -- encode as an E5M2 FP8 float
   crackNum -ffp4     2.5                     -- encode as an FP4 (E2M1) float
   crackNum -ffp4e0m3 3.5                     -- encode as an FP4 (E0M3) sign-magnitude integer
   crackNum -fsp      0x3.2p5                 -- encode as single-precision from hex-float

 Decoding:
   crackNum -i4       0b0110                  -- decode as 4-bit signed integer, from binary
   crackNum -w4       0xE                     -- decode as 4-bit unsigned integer, from hex
   crackNum -f3+4     0b0111001               -- decode as float with 3 bits exponent, 4 bits significand
   crackNum -fbp      0x000F                  -- decode as a brain-precision float
   crackNum -ftf32    19\'h0000F              -- decode as a TensorFloat-32 float
   crackNum -fdp      0x8000000000000000      -- decode as a double-precision float
   crackNum -fhp      0x8000                  -- decode as a half-precision float
   crackNum -ffp4     0b0111                  -- decode as an FP4 (E2M1) float
   crackNum -ffp4e0m3 0b1101                  -- decode as an FP4 (E0M3) sign-magnitude integer
   crackNum -l4 -fhp  64\'hbdffaaffdc71fc60   -- decode as half-precision float over 4 lanes using verilog notation

 GUI:
   crackNum --gui                             -- launch the graphical interface
   crackNum --gui      0xdeadbeef             -- launch the GUI, pre-filled with the given value
   crackNum --gui -fsp 0xdeadbeef             -- launch the GUI, using the given format

 Notes:
   - For encoding:
       - Use -- to separate your argument if it's a negative number.
       - For floats: You can pass in NaN, Inf, -0, -Inf etc as the argument
                     along with a decimal (2.3, -4.1e5) or hexadecimal float (0x2.4p3)
       - FP4 (E2M1) has neither NaN nor Inf, so those inputs are rejected. Finite
         values outside its range of [-6, 6] saturate to the nearest end-point.
       - FP4 (E0M3) is a sign-magnitude integer: a sign bit and a 3-bit magnitude,
         covering -7 to 7, with both a positive and a negative zero. It has no NaN
         and no Inf either, and values outside [-7, 7] saturate to the end-point.
   - For decoding:
       - Use hexadecimal (0x) binary (0b), or N'h (verilog) notation as input.
         Input must have one of these prefixes.
       - You can use _,- or space as a digit to improve readability for the pattern to be decoded
       - With -lN parameter, you can decode multiple lanes of data.
       - If you use verilog input format, then we will infer the number of lanes unless you provide it.

VIM users: You can use the http://github.com/LeventErkok/crackNum/blob/master/crackNum.vim file to use CrackNum directly from VIM. Simply locate your cursor on the text to crack, and use the command :CrackNum options.