#key-hash #fingerprint #key-visialization #visialization

bishop

Library for visualizing keys and hashes using OpenSSH's Drunken Bishop algorithm

8 releases (1 stable)

1.0.0 Oct 17, 2024
0.3.4 Feb 11, 2020
0.3.3 Nov 25, 2019
0.3.1 Oct 27, 2019
0.1.1 Sep 8, 2019

#36 in Visualization


Used in bishop-cli

Apache-2.0/MIT

26KB
409 lines

bishop.rs

+----[drunken]----+
|..+.. oo+o.      |
| *.* o +.o.      |
|= = o * .E+      |
|+. ..+ = +..     |
|o  ...+ S.o      |
| .o .....= .     |
|.. o   .+ +      |
|.        = +     |
|        ..=      |
+----[bishop]-----+

Library and CLI app for visualizing data using The Drunken Bishop algorithm implemented in Rust

Drunken Bishop is the algorithm used in OpenSSH's ssh-keygen for visualising generated keys

Table of Contents:

Crates

Crate Description Version
bishop Library cargo docs
bishop-cli (source) Command-line app cargo

Install

Rust library lives on crates.io

CLI app:

Platform Package
Arch Linux aur
Prebuilts for Linux Github releases

Examples

Using as command-line app

some_data=$(printf foobar | sha256sum | cut -d' ' -f1)
# we are using cut here to crop the filename from sha256sum output

printf $some_data | bishop -sI hex
# `-s` tells bishop to take data from stdin
#
# `-I hex` tells bishop that input data will be in HEX format.
# As an alternative, you might use xxd to turn hex data into binary:

printf $some_data | xxd -r -p | bishop -s
# `-I bin` is implied by default

bishop -i <(printf $some_data) -I hex
# `-i` tells bishop to take data from specified file.
# We are using bash command substitution here, but
# any valid path is allowed, like `bishop -i ~/some.file`

bishop $some_data
# Without `-i` or `-s` bishop expects HEX encoded input in the first argument.
# Note that `-I` is not supported if data is provided as argument

printf foobar | bishop -sI hash
# `-I hash` tells bishop to hash all of its input
# using sha256 before making a randomart.
# Since maximum effective size of input data for random art with default size (17x9)
# is somwhere around 64-128 bytes, this option is extremely useful for large inputs  

All these bishop calls would print this art to console:

Fingerprint of:
c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2

+-----------------+
|    .     .      |
| . + .   +       |
|o + + + = .      |
| * + + O =       |
|  E o.o S        |
| . +.=.o.=       |
|  o.B.=...       |
|   +.+.*  o      |
|    o.o.o. .     |
+-----------------+

Note that input will be echoed only if data is provided as argument or with -I hash. This behavior can be disabled using -q option.

You can read full usage for cli app (also available by --help option) here

Note on char list

You can provide custom char list wich -c option. This is a vector of chars used for fingerprint (represened as string).

Each char is treated as:

Index Description Default
0 Field background
1..n Chars used for drawing .o+=*BOX@%&#/^
n+1 Char for start position S
n+2 Char for last position E

Each non-background char indicates how many times bishop has been on this position.

Start and end chars overwrites the real value.

Char list must be at least 4 chars long, but secure char list is at least 18 chars long and only consists of clearly distinguishable symbols.

Using as library

Cargo.toml

bishop = "0.2.0"

Use latest version as stated on cargo badge above

For AsRef<u8> (slices, vectors)

extern crate bishop;
use bishop::*;

fn main() {
    let data1 = [0u8; 16];
    let data2 = vec![0u8; 16];

    let mut art = BishopArt::new();
    art.input(&data1);
    art.input(&data2);
    println!("{}", art.draw());

    // Using chaining:

    let drawn_art: String = BishopArt::new()
        .chain(&data1)
        .chain(&data2)
        .draw();
    println!("{}", drawn_art);
}

Drawing options and result reusing

use bishop::*;

fn random_art(data: &[u8]) {
    let opts1 = DrawingOptions { top_text: "pass 1".to_string(), ..Default::default() };
    let opts2 = DrawingOptions { bottom_text: "pass 2".to_string(), ..Default::default() };

    // compute field once
    let field = BishopArt::new().chain(data).result();

    // then draw it multiple times with different options
    println!("{}", field.draw_with_opts(&opts1));
    println!("{}", field.draw_with_opts(&opts2));
}

For Read (file, stdin, etc)

use bishop::*;
use std::io::{self, Read};

fn main() {
    // BishopArt implements Write trait
    let mut art = BishopArt::new();
    io::copy(&mut io::stdin(), &mut art);
    println!("{}", art.draw());
}

Full API documentation is available on docs.rs

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~1.3–2MB
~35K SLoC