An implementation of the Drunken Bishop visual fingerprinting algorithm.
The Drunken Bishop 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.
The Drunken Bishop algorithm was designed heuristically, and therefore should not be considered cryptographically strong.
drunken-bishop
The Drunken Bishop 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.
>>> :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.
> :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:
> :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:
> :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:
> :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...|
+-----------------+