Overview
tlsh-rs is a pure Rust implementation of TLSH (Trend Locality Sensitive Hash), built for projects that need fuzzy hashing as a native crate instead of binding to a C or C++ implementation.
This port follows the upstream TLSH algorithm closely, keeps the implementation in safe and portable Rust, and exposes both a library API and a CLI.
Key Features
| Feature | Description |
|---|---|
| Pure Rust | No external crates required for the hashing core |
| Edition 2024 | Modern Rust crate layout and tooling |
| Multiple TLSH Profiles | Supports 128/1, 128/3, 256/1, and 256/3 |
| Streaming Builder | Incremental hashing with TlshBuilder |
| Digest Parsing | Handles raw digests and T1-prefixed digests |
| Distance Calculation | Compare hashes with and without length penalty |
| CLI Included | hash, hash-many, diff, and xref commands |
| JSON + SARIF | Machine-readable outputs for automation pipelines |
| Real Test Vectors | Validated against upstream-compatible reference vectors and local fixtures |
Supported Targets in CI/CD
Windows x64, ARM64
Linux x64, ARM64
macOS Intel, ARM64
Installation
From crates.io
From Source
Build the CLI
Quick Start
# Hash a file
# Compare two files
# Produce SARIF
Usage
Command Line Interface
# Standard TLSH hash
# Raw digest output
# JSON output
# Hash several files
# Compare files or digests
# Cross-reference several inputs
# Read one input from stdin
|
Available Commands
| Command | Description |
|---|---|
hash |
Hash one file or stdin |
hash-many |
Hash multiple files |
diff |
Compare two inputs and return TLSH distance |
xref |
Compare every pair in a set of inputs |
Available Options
| Option | Description |
|---|---|
--profile |
Select 128-1, 128-3, 256-1, or 256-3 |
--raw |
Return raw hex digest instead of T1-prefixed output |
--format |
Output as text, json, or sarif |
--no-length |
Exclude length penalty from TLSH distance |
--threshold N |
Filter xref results above N |
- |
Read one binary input from stdin |
Rust Library
Basic Usage
use ;
let digest = hash_bytes?;
let mut builder = new;
builder.update?;
builder.update?;
let streamed = builder.finalize?;
assert_eq!;
Profile-Specific Hashing
use ;
let digest = hash_bytes_with_profile?;
println!;
Parse and Compare Digests
use TlshDigest;
let left: TlshDigest = "T1F8A0220C0F8C0023CB880800CA33E88B8F0C022AB302C2008A030300300E8A00C83AAC".parse?;
let right: TlshDigest = "T1C6A022A2E0008CC320C083A3E20AA888022A00000A0AB0088828022A0008A00022F22A".parse?;
let diff = left.diff;
let diff_no_length = left.diff_no_length;
Examples
Hash with a specific profile
Export xref as JSON
Export diff as SARIF
Use digest strings directly
Upstream Credit
This project exists because the original TLSH project by Trend Micro exists first:
- Upstream repository: https://github.com/trendmicro/tlsh
Huge thanks to the Trend Micro team for publishing and maintaining TLSH. The original project made the algorithm accessible to the community and gave us a solid reference to validate against.
This Rust port was built so we could use TLSH naturally as a Rust crate inside our own projects, keep deployment simple, and integrate fuzzy hashing into malware analysis and similarity pipelines without depending on a C/C++ runtime.
To the upstream maintainers: your work is genuinely useful, technically elegant, and still doing real damage against boring malware workflows in the best possible way. Thanks for building it and sharing it.
Requirements
- Rust stable
- Cargo
- Rust edition
2024
Contributing
Contributions are welcome. If you want to improve algorithm coverage, add more upstream compatibility vectors, or refine the CLI and release flow, open an issue or a pull request.
- Fork the repository
- Create your branch (
git checkout -b feature/amazing-change) - Commit your changes (
git commit -m 'Add amazing change') - Push your branch (
git push origin feature/amazing-change) - Open a Pull Request
Support the Project
If this crate is useful in your malware analysis, similarity matching, or triage pipelines, you can support the work here:
License
This project is intentionally licensed in a permissive way so it can be used in internal tools, commercial products, research pipelines, and open source projects.
Apache-2.0 OR BSD-3-Clause
Why not MIT?
This repository is a Rust port built from the upstream TLSH work and keeps a license model aligned with the original project published by Trend Micro:
- Upstream repository: https://github.com/trendmicro/tlsh
- Upstream license model:
Apache-2.0 OR BSD-3-Clause
So the safe and honest choice here is to preserve that permissive licensing model instead of relabeling the port as MIT-only.
In practical terms, you can use this crate freely, including in commercial software, but you should preserve the applicable license and attribution notices from the project and its upstream origin when redistributing it.