# `drunken-bishop` The [Drunken Bishop](http://www.dirk-loss.de/sshvis/drunken_bishop.pdf) algorithm is a visual fingerprinting algorithm originally implemented by OpenSSH for visualizing key fingerprints. This package implements OpenSSH's visualization while also offering extra configuration to allow for specialized uses. ## Basic usage The `Data.Digest.DrunkenBishop(drunkenBishop)` function takes a bytestring and produces a multiline string representing the visualization of the hash of that string. ```haskell >>> :set -XOverloadedStrings >>> putStrLn (drunkenBishop "hello!") . . o = o . ^ B . o = . o + ..+.+ = E +o..= .. .. ``` ## Configurable usage The `Data.Digest.DrunkenBishop(DrunkenBishopOptions)` type contains several fields which can be configured to change the operation of the algorithm. The default used by the `drunkenBishop` function are kept in an instance of this type called `drunkenBishopDefaultOptions`. The `drunkenBishopBoardSize` field can set the size of the overall fingerprint image. Note that smaller images will produce "noisier" fingerprints, while larger images will likely produce "sparser" fingerprints. ```haskell > :set -XOverloadedStrings > let opts = drunkenBishopDefaultOptions { drunkenBishopBoardSize = (9, 9) } > putStrLn (drunkenBishopWithOptions opts "hello!") . ... .+.. . ^++. o.=.oo .o.+ =.E oo..= . .. .. ``` The `drunkenBishopInitialPosition` field can change the initial position of the bishop: ```haskell > :set -XOverloadedStrings > let opts = drunkenBishopDefaultOptions { drunkenBishopInitialPosition = Just (0, 0) } > putStrLn (drunkenBishopWithOptions opts "hello!") S . .. . o .. o o.+. .. ++ . .... . o . ..o.. .o.ooo E oo..o. .. . ``` The `drunkenBishopCharMap` field can change the ASCII visualizer used for the cells of the visualization algorithm: ```haskell > :set -XOverloadedStrings > import Data.Char (chr) > let opts = drunkenBishopDefaultOptions { drunkenBishopCharMap = \ c -> chr (fromIntegral (c + 65)) } > putStrLn (drunkenBishopWithOptions opts "hello!") AAAAAAAAAAAAAAAAA AAAAAAAAAAAAABAAA AAAAAAAAAABACAAAA AAAAAAAAAEACAAAAA AAAAAABAOAGABAAAA AAAAAAACAEABACADA AAAAAAAABBDBDAEAQ AAAAAAAAADCBBEAAA AAAAAAAAABBAABBAA ``` Finally, the `drunkenBishopHash` field can change the hash function used by the Drunken Bishop algorithm. This is parametric and can take any type, but must produce a strict `ByteString`. Note that the default MD5 hash produces 128-bit values, so hash functions that produce more values will produce considerably "noisier" fingerprints unless you also change the fingerprint size. The following example uses `hashlazy` from the `cryptohash-sha256` package as an example: ```haskell > :set -XOverloadedStrings > import Crypto.Hash.SHA256 (hashlazy) > let opts = drunkenBishopDefaultOptions { drunkenBishopHash = hashlazy } > putStrLn (drunkenBishopWithOptions opts "hello!") .oo+ . .= o . o . o + . o . = . . = .. . = = ^ . . =o = + o +. o+ o ooo=.o . o . ..= =.o o. .o.E.. o... ``` ## The `drunken-bishop` executable The accompanying `drunken-bishop` executable takes a list of files, or if none are provided, a string on stdin, runs it through the fingerprinting routine, and prints it with a simple ASCII art frame. It accepts a few of the configuration options described above, as well. ``` $ printf "hello!" | drunken-bishop +-----------------+ | | | . | | . o | | = o | | . ^ B . | | o = . o + | | ..+.+ = E| | +o..= | | .. .. | +-----------------+ $ printf "hello!" | drunken-bishop --sha256 +-----------------+ | .oo+ | | . .= o | | . o . o + .| | o . = . . = ..| | . = = ^ . . =o | | = + o +. o+| | o ooo=.o . o| | . ..= =.o o.| | .o.E.. o...| +-----------------+ ```