Parallel Implementation of Common Checksum Algorithms
  • Rust 97.3%
  • Dockerfile 2.1%
  • Shell 0.6%
Find a file
Bryson Steck b8ff444794
Some checks failed
Test-build picca packages / Cargo Registry (push) Successful in 42s
Test-build picca packages / macOS - Release (aarch64-apple-darwin) (push) Successful in 1m20s
Test-build picca packages / Alpine (aarch64-unknown-linux-musl) (push) Successful in 1m41s
Test-build picca packages / Debian 12 (x86_64-unknown-linux-gnu) (push) Successful in 2m25s
Test-build picca packages / Debian 12 (aarch64-unknown-linux-gnu) (push) Successful in 2m34s
Test-build picca packages / Debian 13 (s390x-unknown-linux-gnu) (push) Successful in 56s
Test-build picca packages / macOS - Release (x86_64-apple-darwin) (push) Successful in 1m16s
Test-build picca packages / Debian 12 (powerpc64le-unknown-linux-gnu) (push) Successful in 2m39s
Test-build picca packages / Debian 13 (riscv64gc-unknown-linux-gnu) (push) Successful in 2m22s
Test-build picca packages / Linux - Release (aarch64-unknown-linux-musl) (push) Successful in 58s
Test-build picca packages / Arch Linux (x86_64-unknown-linux-gnu) (push) Successful in 3m54s
Test-build picca packages / Windows - Release (aarch64-pc-windows-msvc) (push) Successful in 3m53s
Test-build picca packages / Linux - Release (loongarch64-unknown-linux-gnu) (push) Successful in 52s
Test-build picca packages / Debian 13 (x86_64-unknown-linux-gnu) (push) Successful in 2m6s
Test-build picca packages / Debian 12 (s390x-unknown-linux-gnu) (push) Successful in 4m37s
Test-build picca packages / Linux - Release (aarch64-unknown-linux-gnu) (push) Successful in 2m32s
Test-build picca packages / Linux - Release (i686-unknown-linux-gnu) (push) Successful in 2m40s
Test-build picca packages / Linux - Release (powerpc64le-unknown-linux-gnu) (push) Successful in 1m0s
Test-build picca packages / Linux - Release (i686-unknown-linux-musl) (push) Successful in 2m43s
Test-build picca packages / Debian 13 (powerpc64le-unknown-linux-gnu) (push) Successful in 5m20s
Test-build picca packages / Linux - Release (sparc64-unknown-linux-gnu) (push) Successful in 51s
Test-build picca packages / Linux - Release (loongarch64-unknown-linux-musl) (push) Successful in 2m59s
Test-build picca packages / Linux - Release (powerpc64le-unknown-linux-musl) (push) Successful in 2m29s
Test-build picca packages / Windows - Release (i686-pc-windows-msvc) (push) Successful in 3m12s
Test-build picca packages / Linux - Release (riscv64gc-unknown-linux-musl) (push) Successful in 2m15s
Test-build picca packages / Linux - Release (s390x-unknown-linux-gnu) (push) Successful in 2m20s
Test-build picca packages / Linux - Release (x86_64-unknown-linux-gnu) (push) Successful in 2m27s
Test-build picca packages / Linux - Release (x86_64-unknown-linux-musl) (push) Successful in 2m40s
Test-build picca packages / Alpine (x86_64-unknown-linux-musl) (push) Successful in 9m19s
Test-build picca packages / Linux - Release (riscv64gc-unknown-linux-gnu) (push) Successful in 4m43s
Test-build picca packages / Windows - Release (x86_64-pc-windows-msvc) (push) Successful in 2m56s
Test-build picca packages / Debian 12 (riscv64gc-unknown-linux-gnu) (push) Successful in -1h59m25s
Test-build picca packages / Ubuntu 22 (aarch64-unknown-linux-gnu) (push) Successful in 2m14s
Test-build picca packages / Gentoo (push) Successful in 12m14s
Test-build picca packages / Ubuntu 22 (powerpc64le-unknown-linux-gnu) (push) Successful in 3m8s
Test-build picca packages / Ubuntu 22 (s390x-unknown-linux-gnu) (push) Successful in 2m1s
Test-build picca packages / Ubuntu 24 (powerpc64le-unknown-linux-gnu) (push) Successful in 2m9s
Test-build picca packages / Debian 13 (aarch64-unknown-linux-gnu) (push) Successful in 15m13s
Test-build picca packages / Ubuntu 24 (x86_64-unknown-linux-gnu) (push) Successful in 58s
Test-build picca packages / Ubuntu 24 (riscv64gc-unknown-linux-gnu) (push) Successful in 2m10s
Test-build picca packages / Create Release (push) Successful in 1m19s
Test-build picca packages / Ubuntu 24 (aarch64-unknown-linux-gnu) (push) Successful in 6m7s
Test-build picca packages / Ubuntu 22 (x86_64-unknown-linux-gnu) (push) Successful in 7m10s
Test-build picca packages / Ubuntu 22 (riscv64gc-unknown-linux-gnu) (push) Successful in -1h59m23s
Test-build picca packages / Ubuntu 24 (s390x-unknown-linux-gnu) (push) Successful in 8m57s
Test-build picca packages / Docker (push) Successful in 34m21s
Test-build picca packages / Rocky 8 (amd64) (push) Successful in 1m4s
Test-build picca packages / Rocky 9 (amd64) (push) Successful in 6m51s
Test-build picca packages / Rocky 10 (amd64) (push) Successful in 7m9s
Test-build picca packages / Rocky 9 (s390x) (push) Failing after 47m44s
Test-build picca packages / Rocky 9 (arm64) (push) Failing after 10m26s
Test-build picca packages / Rocky 8 (arm64) (push) Failing after 28m35s
Test-build picca packages / Rocky 10 (arm64) (push) Failing after 39m9s
Test-build picca packages / Rocky 10 (s390x) (push) Failing after 1h37m16s
Test-build picca packages / Rocky 10 (ppc64le) (push) Failing after 1h20m34s
Test-build picca packages / Rocky 9 (ppc64le) (push) Failing after 42m18s
fix release notes, push instead of test for task
2026-03-25 21:13:08 -06:00
.forgejo/workflows fix release notes, push instead of test for task 2026-03-25 21:13:08 -06:00
benches add blake3 bench, fmt 2026-03-07 19:08:26 -07:00
docker update release workflow, dockerfile 2026-03-20 18:09:28 -06:00
docs remove containerized from runtime, add lib example 2025-12-29 10:44:15 -07:00
examples rename structs again... 2026-02-21 08:42:51 -07:00
man rename all feature to lib, starting to implement tests 2026-01-01 23:16:50 -07:00
singles fix release notes, push instead of test for task 2026-03-25 21:13:08 -06:00
src add test for verify_files, skip files that already appeared 2026-03-21 23:40:29 -06:00
tests add test files 2026-03-20 23:21:33 -06:00
.dockerignore add license info, version bump 2025-08-19 22:28:22 -06:00
.gitignore remove old case study scripts, update readme 2026-03-22 10:22:30 -06:00
.rustfmt.toml maintenance, generalize containers, year bump 2025-12-28 10:40:11 -07:00
Cargo.lock fix release notes, push instead of test for task 2026-03-25 21:13:08 -06:00
Cargo.toml fix release notes, push instead of test for task 2026-03-25 21:13:08 -06:00
LICENSE move handle waits into separate function for generate and verify functions 2025-12-31 17:41:55 -07:00
README.md update cargo commands, update deps 2026-03-22 10:32:01 -06:00
Taskfile.yml remove old case study scripts, update readme 2026-03-22 10:22:30 -06:00

picca

picca (acronym for a Parallel Implementation of Common Checksum Algorithms) is a relatively small Rust program and wrapper library intented to speed up hashing files by reading multiple files at once.

Awesome Features!

What CAN picca do?

picca can:

  1. Hash any file using any one of 50 algorithms! Current options can be found in the source code here.
  2. Read checksum files in BSD and GNU Tagged formats, and verify the files listed.
  3. Hash each file up to the number of cores/threads your CPU has, or a custom amount.
  4. Be a potential replacement for the UNIX cksum utility and the individual algorithmic checksum utilities (sha256sum, b2sum, etc.)
  5. Ignore common errors, such as missing files, and produce quiet output.

What is picca NOT?

  1. A custom implementation of each hashing algorithm. The hash algorithims are sourced from RustCrypto's hashes libraries.

How do I use such an awesome program?

picca operates mostly (if not, the same) as the UNIX cksum program. Here is a non-exhaustive list of examples:

  • On it's own, picca will hash whatever comes in from standard input using the SHA256 algorithm.
    $ picca
    ^D
    e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  -
    $ echo hi | picca
    98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4  -
    
  • Using the -a flag, you can change the algorithm (only with the single binary, see the section Installing the binaries for what that means).
    $ echo hi | picca -a md5
    764efa883dda1e11db47671c4a3bbd9e  -
    
  • Instead of reading from standard input, you can specify file(s) as arguments to hash the contents of them instead.
    $ picca LICENSE
    3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986  LICENSE
    
  • By default, picca will read and hash up to n files simultaneously in separate threads, where n is the amount of cores your CPU has. You can adjust the amount of threads using the -t flag.
    # use only 4 threads
    $ picca -t4 LICENSE
    3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986  LICENSE
    
    • If less than n files are specified, picca will ignore the thread count you specify and spawn as many threads as there are files.
  • You can also use picca to verify the hash of files using the -c flag.
    $ cat files.sha256
    3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986  LICENSE
    $ picca -c files.sha256
    LICENSE: OK
    
    • picca supports BSD-style and GNU-style checksum formats.
    • For BSD-style checksums, if the hashes in your file are different than SHA256, you must specify the algorithm with -a.

picca is also available for use in your Rust program as a crate! See the examples to learn how to use it.

Project hosting distribution

The picca project is hosted on two separate Forgejo instances, Codeberg and my own (hereafter refered to as "my forge" or "forge"), mainly because I enjoy self-hosting, but also as an experiment to see if projects like these can survive being hosted like this. Here is what lives on each:

Both Codeberg and My Forge

  • The raw Git repository
    • All changes that occur on either platform are synced to the other immediately
  • Forgejo releases

Codeberg only

  • Issue management and pull requests (to welcome community contributions)
  • Project management (see the picca project)

My Forge only

Installing the Binaries

picca offers two categories of installs, refered to hereafter as "single" and "standalone" respectively:

  1. The singular picca binary that can hash with any of the supported algorithms (defaults to SHA256)
  2. Individual binaries named after the only algorithm they can hash with, such as md5sum, blake3sum, etc.

The single and standalone binaries can be installed in several different ways depending on what you prefer and/or what your operating system offers.

  • Platform Agnostic
    • Cargo (building and installing from source)
    • Docker/Podman
  • Linux
    • Alpine 3.x
    • Arch
    • Debian 12, 13/Ubuntu 22, 24
    • Enterprise Linux (Rocky/Red Hat) 8, 9, 10
    • Gentoo
    • Ubuntu 22, 24
    • Individual Binaries
  • macOS Binaries
  • Windows Binaries

Cargo

This is essentially just compiling it yourself and putting it in the same $PATH location as Cargo so it can be invoked.

# clone the repository
# you can use forge.steck.dev instead of codeberg.org if you wish.
git clone https://codeberg.org/bryson/picca && cd picca
# to install the single binary:
cargo install --features bin --bin picca --path .
# to install all the standalone binaries
for i in $(ls -d singles/*/); do
  cargo install --path $i
done
# to install only a certain standalone binary, replace <NAME> with the name of the binary:
cargo install --path singles/<NAME>

Docker/Podman

Not really "installing" per se, but allows you to use it in an isolated environment.

A OCI image is available for use in an OCI-compatible container environment like Docker or Podman. The following examples use Docker.

# Run in a bare minimum container. -i is required to read from stdin, but I like to add --rm so I can skip the step of removing the container after.
docker run --rm -i forge.steck.dev/bryson/picca
# Mount file and scan it. -i is no longer needed since we won't read from stdin, but all arguments after the image name are passed to picca.
docker run --rm -v ./file:/tmp/file forge.steck.dev/bryson/picca /tmp/file

Adding to your image

FROM forge.steck.dev/bryson/picca:latest AS picca
COPY --from=picca /usr/local/bin/picca /usr/local/bin

Alpine Linux

Follow these instructions to set up the Alpine repository on your system.

Arch Linux

Follow these instructions to set up the Arch repository on your system.

Debian/Ubuntu Linux

Follow these instructions to set up the Apt repository on your system.

Enterprise Linux (Rocky, Red Hat)

Follow these instructions to set up the DNF repository on your system.

Gentoo Linux

The Gentoo package is hosted in a Git-based overlay on my forge.

# Use eselect to add the overlay
sudo eselect repository add bryson-steck git https://forge.steck.dev/pkg/gentoo.git
# Use emaint to sync the overlay
sudo emaint sync -r bryson-steck
# Finally, emerge picca
sudo emerge -av sys-apps/picca

Individual Binaries

If your distro doesn't appear above or has different requirements (architecture, libc, etc.), you can use one of the several release binaries and install them in a place you can find and use it.

# assuming that ~/bin is in $PATH:
cd ~
curl https://codeberg.org/bryson/picca/releases/download/v0.15.2/picca-v0.15.2-x86_64-unknown-linux-gnu.tar.xz | tar xvf - bin/picca

macOS

macOS binaries aren't packaged in an installer format, you must install them in a place you can find it.

# assuming that ~/bin is in $PATH:
cd ~
curl https://codeberg.org/bryson/picca/releases/download/v0.15.2/picca-v0.15.2-aarch64-apple-darwin.tar.xz | tar xvf - bin/picca

Windows

Windows binaries aren't packaged in an installer format, you must install them in a place you can find it.

# assuming that ~\bin is in $env:PATH:
Set-Location ~\Downloads
Invoke-WebRequest "https://codeberg.org/bryson/picca/releases/download/v0.15.2/picca-v0.15.2-x86_64-pc-windows-msvc.zip" -OutFile "picca-v0.15.2-x86_64-pc-windows-msvc.zip"
Expand-Archive ".\picca-v0.15.2-x86_64-pc-windows-msvc.zip"
Move-Item ".\picca-v0.15.2-x86_64-pc-windows-msvc\bin\picca.exe" ~\bin

Installing the Library

picca is also available for use as a crate in your Rust program. Simply add it to your dependencies using Cargo:

cargo add picca
# you can also use the git repo if you wish.
cargo add --git https://codeberg.org/bryson/picca picca

Benchmarks

Some benchmarks are available for your use to see how picca stands up against your coreutils binaries. Simply run cargo bench to run the following benchmarks:

  • blake3 - This will test an algorithm that is already multithreaded against picca which is adding the ability to read multiple files at once (UNIX only, b3 must be available on your system).
  • sha256 - This tests a conventional, single threaded algorithm to allow picca to use more processing power that it leaves behind for reading the files.

Each benchmark creates 100, 300, and 500 random, 4MB files and runs the local binary and picca against those files to see if they provide any speed benefit. The more the files, the easier to see if it provides faster speeds.