crackNum 3.26 → 3.27
raw patch · 4 files changed
+84/−18 lines, 4 files
Files
- CHANGES.md +17/−1
- README.md +42/−4
- crackNum.cabal +1/−1
- src/CrackNum/Main.hs +24/−12
CHANGES.md view
@@ -1,7 +1,23 @@ * Hackage: <http://hackage.haskell.org/package/crackNum> * GitHub: <http://github.com/LeventErkok/crackNum/> -* Latest Hackage released version: 3.26, 2026-08-19+* Latest Hackage released version: 3.27, 2026-08-20++### Version 3.27, 2026-08-20++ * There is now a Linux binary distribution, alongside the macOS one: see the+ Releases page. It ships the `crackNum` executable, a copy of `z3` (which crackNum+ shells out to for every operation), the Tcl/Tk GUI script, and a README. Both+ binaries are statically linked, so there is no libc or distribution requirement:+ they run as-is on any x86_64 Linux, old or new. The GUI additionally needs `wish`,+ which does have to come from your system.++ * `--gui` now also looks for `crackNum.tcl` next to the crackNum executable itself,+ after `$CRACKNUM_TCL` and the PATH but before the cabal data-directory. A binary+ distribution carries the script alongside the binary, where the data-directory+ baked in at build time names a path from the build machine that does not exist+ on the user's; the GUI now works in such a bundle however it is unpacked or+ copied, rather than only when the script was also placed on the PATH. ### Version 3.26, 2026-08-19
README.md view
@@ -13,13 +13,47 @@ ### Installation +#### Prebuilt binaries (nothing to build, no Haskell toolchain)++The easiest way to get crackNum is from the+[Releases page](https://github.com/LeventErkok/crackNum/releases). 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](http://hackage.haskell.org/package/sbv) and delegates the-actual floating-point reasoning to an SMT solver, so you also need-[z3](https://github.com/Z3Prover/z3) on your `PATH`.+actual floating-point reasoning to an SMT solver, so installed this way you also+need [z3](https://github.com/Z3Prover/z3) on your `PATH`. (The prebuilt bundles+above carry their own copy, so there is nothing extra to install.) ### Supported formats @@ -314,9 +348,13 @@  +If you installed from a [release bundle](#prebuilt-binaries-nothing-to-build-no-haskell-toolchain)+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 you need a clone of the repository to build it. You also-need the Swift compiler that comes with the Xcode Command Line Tools+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`): ```
crackNum.cabal view
@@ -1,6 +1,6 @@ Cabal-version : 2.2 Name : crackNum-Version : 3.26+Version : 3.27 Synopsis : Crack various integer and floating-point data formats Description : Crack IEEE-754 and other float formats and arbitrary sized words and integers, showing the layout. .
src/CrackNum/Main.hs view
@@ -30,11 +30,12 @@ import qualified Control.Exception as C import Text.Read (readMaybe)-import System.Environment (getArgs, getProgName, withArgs, lookupEnv)+import System.Environment (getArgs, getProgName, withArgs, lookupEnv, getExecutablePath) import System.Console.GetOpt (ArgOrder(Permute), getOpt, ArgDescr(..), OptDescr(..), usageInfo) import System.Exit (exitFailure, ExitCode(..)) import System.IO (hPutStr, stderr) import System.Directory (findExecutable, doesFileExist)+import System.FilePath (takeDirectory, (</>)) import System.Process (rawSystem) import qualified System.Info as Info @@ -336,11 +337,14 @@ tclRelPath = "GUI/tclGUI/crackNum.tcl" -- | Locate the Tcl/Tk GUI script. Normally it is installed together with the--- binary, so this just works; we look in three places, in order:+-- binary, so this just works; we look in four places, in order: -- -- 1. $CRACKNUM_TCL, if set: an explicit override, mirroring $CRACKNUM_GUI on macOS. -- 2. The PATH, so a source checkout can shadow the installed copy while hacking.--- 3. The copy cabal installed in our data-directory.+-- 3. Next to the executable itself. This is what makes a relocatable binary+-- distribution work: in one the data-directory below was baked in on the+-- build machine, and names a path that does not exist on the user's.+-- 4. The copy cabal installed in our data-directory. locateTcl :: IO FilePath locateTcl = do mbEnv <- lookupEnv "CRACKNUM_TCL" case mbEnv of@@ -351,20 +355,28 @@ , "" , " " ++ p ]- Nothing -> do mbPath <- findExecutable "crackNum.tcl"+ Nothing -> do beside <- besideExe+ installed <- getDataFileName tclRelPath+ mbPath <- findExecutable "crackNum.tcl" case mbPath of Just p -> pure p- Nothing -> do installed <- getDataFileName tclRelPath- ok <- doesFileExist installed- if ok- then pure installed- else die (noTcl installed)- where noTcl installed =+ Nothing -> search [beside, installed] (noTcl beside installed)+ where -- NB. getExecutablePath resolves symlinks, so this finds the script even+ -- when the binary is reached through a link from elsewhere on the PATH.+ besideExe = do exe <- getExecutablePath+ pure (takeDirectory exe </> "crackNum.tcl")++ search [] onFail = die onFail+ search (c:cs) onFail = do ok <- doesFileExist c+ if ok then pure c else search cs onFail++ noTcl beside installed = [ "Cannot find the CrackNum GUI script (crackNum.tcl)." , "" , "Looked in:" , " $CRACKNUM_TCL (not set)" , " crackNum.tcl on your PATH (not found)"+ , " " ++ beside , " " ++ installed , "" , "This script is normally installed along with crackNum, so seeing this"@@ -385,8 +397,8 @@ -- them. The GUI itself calls back into this executable to do the actual cracking. -- -- On macOS the GUI is a Swift/AppKit app; CRACKNUM_GUI can override the .app bundle--- location. On Linux the GUI is a Tcl/Tk script; both 'wish' and 'crackNum.tcl' are--- located via PATH.+-- location. On Linux the GUI is a Tcl/Tk script; 'wish' is located via PATH, and+-- 'crackNum.tcl' via 'locateTcl'. launchGUI :: [String] -> IO () launchGUI vals | Info.os == "darwin"