Add .pylintrc and some documentation + fixes to shut pylint up.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2024-05-22 12:05:20 -07:00
parent 840e878748
commit 660a0cb60c
5 changed files with 736 additions and 2 deletions

View File

@@ -1,3 +1,5 @@
"Generate a graphic based on the hash of an input file."
import argparse
import hashlib
from pathlib import Path
@@ -26,6 +28,9 @@ PALETTES = {
def main() -> None:
"Main function entrypoint."
# pylint: disable=invalid-name
MATRIX_CHOICES = {
"nibble": "Use each nibble (4 bits) of the hash to generate a matrix",
"randomart": "Use the SSH 'randomart' algorithm to generate a matrix",

View File

@@ -1,3 +1,4 @@
"All things that turn a numeric matrix into a colored matrix."
import abc
from typing import Sequence
@@ -8,10 +9,20 @@ StrMatrix = Sequence[Sequence[str]]
class Colorizer(metaclass=abc.ABCMeta):
"""
The base Colorizer class.
A colorizer turns a numeric matrix into a color matrix, colors being represented by strings of
HTML colors.
"""
@abc.abstractmethod
def colorize(self, matrix: Matrix) -> StrMatrix:
"""
Colorize a matrix.
:param matrix: the matrix to colorize.
:returns: the colorized matrix.
"""
@@ -19,9 +30,25 @@ Palette = Sequence[str]
class PaletteColorizer(Colorizer):
"""
A palette colorizer.
This colorizer will use a palette to colorize its inputs. A palette is 16 colors.
"""
def __init__(self, palette: Palette) -> None:
"""
Create a new palette colorizer for a given palette.
:param palette: the palette to use for this colorizer.
"""
assert len(palette) == 16, "palette must contain exactly 16 colors"
self.palette = palette
def colorize(self, matrix: Matrix) -> StrMatrix:
"""
Colorize the given matrix using this colorizer's palette.
:param matrix: the matrix to colorize.
:returns: the colorized matrix.
"""
return [[self.palette[v] for v in row] for row in matrix]

View File

@@ -1,3 +1,4 @@
"All things that turn a hash into a matrix."
import abc
from typing import Sequence
@@ -6,7 +7,20 @@ Matrix = Sequence[Sequence[int]]
class Matricizer(metaclass=abc.ABCMeta):
"""
The base Matricizer class.
A matricizer turns a collection of hash bytes into a matrix of values between 0x0 and 0xf
(inclusive). The method by which this is done is up to the matricizer.
"""
def __init__(self, w: int, h: int) -> None:
"""
Create a new matricizer for the given dimensions.
:param w: the width of the output matrix.
:param h: the height of hte output matrix.
"""
self.w = w
self.h = h
@@ -14,10 +28,20 @@ class Matricizer(metaclass=abc.ABCMeta):
def matricize(self, data: bytes) -> Matrix:
"""
Convert a hash to a matrix of given width and height.
:param data: the hash data to turn into a matrix.
:returns: the matrix converted from the hash data.
"""
class NibbleMatricizer(Matricizer):
"""
A matricizer that converts a hash based on all of the nibbles in the hash.
While dimensions are not enforced by this matricizer, it is strongly recommended to use the
dimensions provided by the `NibbleMatricizer.DIMENSIONS` member.
"""
DIMENSIONS = {
"md5": (8, 4),
"sha1": (8, 5),
@@ -26,9 +50,13 @@ class NibbleMatricizer(Matricizer):
"sha384": (12, 8),
"sha512": (16, 8),
}
def matricize(self, data: bytes) -> Matrix:
"""
Convert a set of bytes to a list of rows of nibbles.
:param data: the hash data to turn into a matrix.
:returns: the matrix converted from the hash data.
"""
nibbles = []
@@ -39,7 +67,8 @@ class NibbleMatricizer(Matricizer):
if len(nibbles) != self.w * self.h:
raise ValueError(
f"input data length ({len(nibbles)}) must match matrix dimensions ({self.w}x{self.h} = {self.w * self.h})"
f"input data length ({len(nibbles)}) must match matrix dimensions "
f"({self.w}x{self.h} = {self.w * self.h})"
)
cols = []
@@ -54,10 +83,31 @@ class NibbleMatricizer(Matricizer):
class RandomartMatricizer(Matricizer):
"""
A matricizer that converts hash data into a matrix based on the "randomart" algorithm from
ssh-keygen.
See: https://github.com/openssh/openssh-portable/blob/fc5dc092830de23767c6ef67baa18310a64ee533/sshkey.c#L1014
"""
def matricize(self, data: bytes) -> Matrix:
"""
Create a matrix based on the "randomart" algorithm from ssh-keygen.
The algorithm is as follows:
1. Choose the point in the middle of the matrix.
2. Iterate through the data, two bits at a time.
3. If the low bit is set, then move the pointer right. Otherwise, move left.
4. If the high bit is set, then move the pointer down. Otherwise, move up.
5. If stepping in either direction would move us outside of the matrix, then don't move in
that direction.
6. At the end of each step, increment the value in the matrix by one.
:param data: the hash data to turn into a matrix.
:returns: the matrix converted from the hash data.
"""
rows = [[0] * self.w for _ in range(self.h)]
c = self.w // 2
r = self.h // 2
@@ -74,6 +124,6 @@ class RandomartMatricizer(Matricizer):
c = min(max(c, 0), self.w - 1)
r = min(max(r, 0), self.h - 1)
# max value is 0xf
if rows[r][c] < 0xf:
if rows[r][c] < 0xF:
rows[r][c] += 1
return rows

View File

@@ -1,9 +1,14 @@
"SVG-related functions."
from .colorizer import StrMatrix
def gensvg(matrix: StrMatrix, square_size: int) -> str:
"""
Generate an SVG based on a given matrix.
:param matrix: the color matrix to generate the SVG for.
:param square_size: the size of the squares generated, in pixels.
:returns: the full generated SVG as a string.
"""
h = len(matrix)
w = len(matrix[0])