# ssdeep: a fuzzy hashing API for files that are almost the same

> ssdeep is a C library and command line tool that computes context triggered piecewise hashes so you can compare files that differ slightly, and it exposes the whole thing through four functions and a header file. It answers a question cryptographic digests cannot, and it comes with a licence and a release history that need checking before you depend on it.

**ssdeep-project/ssdeep** — Fuzzy hashing API and fuzzy hashing tool

- Repository: https://github.com/ssdeep-project/ssdeep
- Website: https://ssdeep-project.github.io/ssdeep/index.html
- Stars: 800 · Forks: 126
- Language: C
- License: GPL-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/ssdeep-project-ssdeep

## Similarity, not equality, is the question being answered

A cryptographic digest answers one question: are these two byte sequences the same. It gives no useful answer for a file that has been renamed, re-encoded with one changed header byte, or padded. ssdeep was written for the other question, whether two files are close enough to be the same content in a different shape.

The technique is context triggered piecewise hashing, and the reference given at the end of the API documentation is Jesse D. Kornblum's paper "Identifying almost identical files using context triggered piecewise hashing", published in Digital Investigation in September 2006. The repository also carries a `FILEFORMAT` file at the top level, which describes how a signature is encoded.

That distinction decides the audience. ssdeep belongs in file indexing, corpus deduplication, malware sample clustering and evidence triage, where the same payload arrives under many names. It does not belong in a deployment pipeline checking that a download matches a published checksum, where a near match is not good enough.

The project is a C library with a command line tool on top of it. The primary language of the repository is C, and the source tree also holds C++ files.

## Four functions and one fixed size buffer

The public API is small enough to read in a minute. You include the header, allocate a result buffer, and call one of the hashing functions.

```c
#include <fuzzy.h>
```

There are three ways to produce a signature. One takes a buffer of bytes you already have in memory.

```c
int fuzzy_hash_buf(const unsigned char *buf,
                   uint32_t      buf_len,
                   char          *result);
```

Another takes an open file handle, and a third takes a filename and opens the file itself. All three write into a `result` buffer that the documentation is emphatic about: you must allocate it to hold `FUZZY_MAX_RESULT` characters before calling, otherwise you are writing past the end of your own memory. The function returns zero on success and one on error.

Comparing two signatures is the fourth function.

```c
int fuzzy_compare(const char *sig1, const char *sig2);
```

It returns a value from 0 to 100 indicating the match score, and a score of zero means the signatures did not match. There is no threshold in the library itself, so the decision of what counts as similar is left to the calling code. That is a real design choice, and it means you have to pick a cut-off for your data rather than inherit one.

One small responsibility sits with the caller as well: appending the filename to the output is the user's job, as the documentation states for both the buffer and file variants.

## Three toolchains, one shared header

Building an application against the library means including `fuzzy.h` and linking the fuzzy library. On a Unix like system with gcc, the documentation gives this compile line for the sample program.

```bash
$ gcc -Wall -I/usr/local/include -L/usr/local/lib sample.c -lfuzzy
```

Windows has two documented paths. MinGW links the DLL directly.

```bash
C:\> gcc -Wall -Ic:\path\to\includes sample.c fuzzy.dll
```

For Microsoft Visual C the DLL cannot be used directly, and the documentation explains that you first create a `.lib` file with the Microsoft LIB tool from the shipped `.def` file.

```bash
C:\> lib /machine:i386 /def:fuzzy.def
```

The resulting library is then used when compiling.

```bash
C:\> cl sample.c fuzzy.lib
```

The Windows package includes the Win32 DLL and the `.def` file, and the source tree contains `fuzzy-win32res.rc.in` and `ssdeep-win32res.rc.in` for the Windows resources, with `win.sh` among the shell scripts. A sample program that uses the API is in `sample.c`, so you have something that compiles once you have the library.

For the command line tool itself, the usage information lives in the man page, viewable as `man ./ssdeep.1`, with the generated source `ssdeep.1.in` also documented, and Windows users are pointed at `README.TXT`.

## The source tree separates the algorithm from the interface

The repository layout shows a deliberate split. The core sits in `fuzzy.c` with its public header `fuzzy.h`, and the pieces around it are separate files: `edit_dist.c` and `edit_dist.h` for the edit distance work, `match.cpp` and `match.h` for matching, `dig.cpp` for the digest step, `engine.cpp` and `cycles.cpp` for the chunking engine, `sum_table.h` for the rolling sum table, `filedata.cpp` and `filedata.h` for file reading.

The command line front end is separate again, in `main.cpp`, `main.h` and `ui.cpp`, which is what lets the same library serve both the tool and third party programs.

Build files are autotools based: `configure.ac`, `Makefile.am`, `bootstrap` and an `m4/` directory. There is also a `Doxyfile`, so the API can be generated as documentation, and an `AUTHORS` file, a `ChangeLog`, a `NEWS` file and a `TODO`.

The test scripts are worth noting. `test-against-old.sh` compares the current build against an older one, which is a sensible check for a tool whose output is a signature format, and `world.sh` and `normal.sh` sit alongside it. The presence of a documented file format and regression scripts tells you the signature encoding is treated as a compatibility surface, not an implementation detail.

## A percentage score leaves the threshold to you

The main limitation is in the API contract itself. `fuzzy_compare` returns a number between 0 and 100 and stops there. It does not tell you whether two files are the same sample, only how close two signatures look, and the level at which a 78 becomes a match depends entirely on your corpus.

The second limitation is the buffer contract. Because the caller must allocate `FUZZY_MAX_RESULT` characters for the result, a program that hashes in a loop has to manage that allocation on every iteration. Get it wrong and you have a memory corruption bug rather than a wrong answer, since the library will happily write into whatever pointer you hand it.

A third is portability of the toolchain. The Unix path is a standard autotools build, but the Windows path is described in terms of MinGW and a manual `.lib` creation step for MSVC users, which is more assembly than a Python developer or a Go developer usually wants in a dependency.

If your need is exact integrity verification, ssdeep is the wrong tool entirely, and a plain cryptographic digest of the file is both simpler and stronger, since a fuzzy score can be high for two genuinely different files that happen to share structure.

## Commits continue while tagged releases stopped in 2017

The maintenance picture needs the two dates read together. The repository is not archived and the last push was on 2026-08-13, so work is still landing on the master branch. The published releases, however, stop much earlier: version 2.14.1 on 2017-11-07, version 2.14 on 2017-09-12 and version 2.13 on 2017-06-27.

So there is a long gap between the newest tag and the newest commit. If you install from a package manager or a source tarball you are likely getting 2017 code; if you build from master you are getting something nearly nine years newer than any release, with no tag to tell you which stable point to trust.

The licence is GPL-2.0, with the `COPYING` file at the repository root. Linking the library into your own program therefore carries copyleft obligations for the combined work, unlike a permissive licence where you can keep your source closed. This is a reading of the licence terms rather than legal advice, and it is the single most important thing to settle before you embed the library in a commercial product, because a shared library linked at runtime and a library compiled into a binary are different questions for a GPL reviewer.

For a project this old, the upgrade cost also includes the surrounding toolchain. The build uses autotools with a `bootstrap` step, so a modern minimal container image may need autotools installed before it can build the source.

## Conclusion

Adopt ssdeep when you need to detect near duplicates, such as a renamed or lightly edited sample in a file corpus, and skip it when you need a cryptographic guarantee, since a similarity score is not an integrity check. Verify first that your platform can build the library, because the packaging is an autotools project with a hand written Windows path, and that the version you pick still matches the file format documented in FILEFORMAT.

## FAQ

### What is ssdeep used for?

ssdeep computes fuzzy hashes so you can tell whether two files are nearly identical even when they are not byte for byte equal. It is aimed at file indexing, deduplication and sample clustering, not at exact integrity verification.

### How do I use the ssdeep API in my own program?

Include the header with `#include <fuzzy.h>`, allocate a result buffer of `FUZZY_MAX_RESULT` characters, then call `fuzzy_hash_buf`, `fuzzy_hash_file` or `fuzzy_hash_filename`. A sample program is in `sample.c` and the API is documented in the fuzzy hashing header file.

### What does fuzzy_compare return?

It returns a value from 0 to 100 giving the match score of two signatures, and a score of zero means the signatures did not match. The library does not apply a threshold, so the caller decides what counts as a match.

### How do I compile against ssdeep on Windows with MSVC?

The Windows package ships a Win32 DLL and a `.def` file. MSVC cannot use the DLL directly, so you create a library file with `lib /machine:i386 /def:fuzzy.def` and then compile with `cl sample.c fuzzy.lib`.

### What licence does ssdeep use and is it still being worked on?

The repository is under GPL-2.0, with the licence text in the COPYING file at the repository root. The repository is not archived and the last push was on 2026-08-13, but the most recent tagged release is version 2.14.1 from 2017-11-07.

## Sources

- [License: GPL-2.0](https://github.com/ssdeep-project/ssdeep/blob/master/LICENSE)
- [Project website](https://ssdeep-project.github.io/ssdeep/index.html)
- [README](https://github.com/ssdeep-project/ssdeep/blob/master/README.md)
- [Releases](https://github.com/ssdeep-project/ssdeep/releases)
- [ssdeep-project/ssdeep on GitHub](https://github.com/ssdeep-project/ssdeep)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ssdeep-project-ssdeep
