PHPackages                             legitphp/hash-money - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. legitphp/hash-money

ActiveLibrary[Image &amp; Media](/categories/media)

legitphp/hash-money
===================

A performance-oriented PHP package for image hashing algorithms using VIPS.

v1.0.0(11mo ago)026[1 issues](https://github.com/mferrara/hash-money/issues)[8 PRs](https://github.com/mferrara/hash-money/pulls)MITPHPPHP ^8.3CI passing

Since Jun 15Pushed 1mo agoCompare

[ Source](https://github.com/mferrara/hash-money)[ Packagist](https://packagist.org/packages/legitphp/hash-money)[ Docs](https://github.com/mferrara/hash-money)[ GitHub Sponsors](https://github.com/legitphp)[ RSS](/packages/legitphp-hash-money/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (3)Versions (11)Used By (0)

Hash Money 💰
============

[](#hash-money-)

[![Latest Version on Packagist](https://camo.githubusercontent.com/4c66561525fc60aa7669e3b216cb0223ffce4f336b90020d1f0aff52ae6a0c7c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c656769747068702f686173682d6d6f6e65792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/legitphp/hash-money)[![Tests](https://camo.githubusercontent.com/3187b4c9d732239a21f881774588fa3c2fd13d30ffdf083ad0dc65e744728671/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d666572726172612f686173682f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/mferrara/hash/actions/workflows/run-tests.yml)[![Total Downloads](https://camo.githubusercontent.com/42adbf16fe156ad28e165fc6d0f3434e31ed545a5985377741faddb271bc1aaf/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c656769747068702f686173682d6d6f6e65792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/legitphp/hash-money)[![PHP Version](https://camo.githubusercontent.com/761f4057880007ac7a0f46a0123075cc07409af0000e2733f6b5847bc05252df/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6c656769747068702f686173682d6d6f6e65793f7374796c653d666c61742d737175617265)](https://packagist.org/packages/legitphp/hash-money)

**Cache rules everything around me.**

Onions? Eggs? What do you like with your hash?

Hash Money
==========

[](#hash-money)

We're serving up a performance-oriented and opinionated collection of similarity hashing algorithms for PHP. Whether you're comparing images, finding duplicates, or measuring how alike things are - we got you covered. We're riding dirty with [php-vips](https://github.com/php-vips/php-vips) for maximum speed. Get your FFI poppin'.

Features
--------

[](#features)

- 🚀 **Multiple Algorithms**: Perceptual Hash (pHash), Difference Hash (dHash), and Color Histogram Hash
- 🔒 **Type Safety**: Value objects ensure you can't compare incompatible hashes
- 🎯 **Configurable Bit Sizes**: Support for 8, 16, 32, and 64-bit hashes
- ⚡ **High Performance**: Optimized VIPS operations for speed
- 🛠️ **Clean API**: Simple static methods with full IDE support
- 🧩 **Extensible**: Strategy pattern makes adding new algorithms easy

Algorithms
----------

[](#algorithms)

### Perceptual Hash (pHash)

[](#perceptual-hash-phash)

DCT-based algorithm that's robust to scaling, aspect ratio changes, and minor color variations. Best for finding near-duplicate images.

- Uses Discrete Cosine Transform (DCT)
- More computationally intensive but highly accurate
- Excellent for matching images with color/brightness variations
- Based on the work from [VincentChalnot/PerceptualHash](https://github.com/VincentChalnot/perceptual-hash)

### Difference Hash (dHash)

[](#difference-hash-dhash)

Gradient-based algorithm that's faster than pHash and good at detecting similar images. It works by comparing adjacent pixels to encode the image structure.

- Analyzes gradient changes between adjacent pixels
- Faster computation than pHash
- Good for detecting cropped or slightly modified images
- More sensitive to rotation than pHash

### Color Histogram Hash

[](#color-histogram-hash)

Color distribution-based algorithm that captures global color patterns in images. Particularly effective for finding images with similar color palettes.

- Uses HSV color space for robustness to illumination changes
- Quantizes colors into bins (8×4×4 by default)
- Excellent for detecting color-shifted or filtered variants
- Complements spatial hashes by focusing on color information
- **Enhanced bit distribution**: Now uses all 64 bits effectively with proper mixing
- **Improved uniqueness**: Fixed algorithm provides much better hash diversity

### MashedHash 🥔

[](#mashedhash-)

A comprehensive image fingerprint that "mashes" together multiple image characteristics into a single 64-bit hash. This algorithm analyzes 11 different aspects of an image to create a rich signature that captures both content and style.

**Bit Layout (64 bits total):**

- **Bits 0-3**: Colorfulness level (0-15) - Detects grayscale vs vibrant images
- **Bits 4-7**: Edge density (0-15) - Measures detail and texture complexity
- **Bits 8-11**: Entropy/complexity (0-15) - Identifies simple vs complex compositions
- **Bits 12-14**: Aspect ratio class (0-7) - Captures image orientation and format
- **Bit 15**: Border flag - Detects images with uniform borders (common in social media)
- **Bits 16-31**: Color distribution (16 bits) - Analyzes RGB channel characteristics
- **Bits 32-39**: Spatial color layout (8 bits) - Tracks dominant colors by quadrant
- **Bits 40-47**: Brightness pattern (8 bits) - Encodes luminance distribution
- **Bits 48-55**: Texture features (8 bits) - Captures directional patterns
- **Bits 56-59**: Dominant color count (0-15) - Estimates color palette size
- **Bits 60-63**: Special indicators (4 bits) - Flags for text, uniform regions, etc.

**Why use MashedHash?**

- **Rich metadata**: Unlike single-feature hashes, it captures multiple image properties
- **Versatile matching**: Can identify similar images even with different modifications
- **Social media ready**: Detects common edits like borders, filters, and crops
- **Fast comparison**: Despite encoding 11 features, it's still just a 64-bit integer
- **Complementary**: Works best when combined with pHash or dHash for robust matching

Requirements
------------

[](#requirements)

- PHP 8.3+ (64-bit required)
- [libvips](https://github.com/libvips/libvips) 8.7+
- [php-vips](https://github.com/libvips/php-vips) extension 2.5+

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require legitphp/hash-money
```

### Installing libvips

[](#installing-libvips)

**Ubuntu/Debian:**

```
sudo apt install libvips-dev
```

**macOS:**

```
brew install vips
```

**Then install the PHP extension:**

```
pecl install vips
```

Usage
-----

[](#usage)

### Basic Usage

[](#basic-usage)

```
use LegitPHP\HashMoney\PerceptualHash;
use LegitPHP\HashMoney\DHash;
use LegitPHP\HashMoney\ColorHistogramHash;
use LegitPHP\HashMoney\MashedHash;

// Generate a perceptual hash
$pHash = PerceptualHash::hashFromFile('/path/to/image.jpg');
echo $pHash->toHex(); // e.g., "f0e1d2c3b4a59687"

// Generate a difference hash
$dHash = DHash::hashFromFile('/path/to/image.jpg');
echo $dHash->toBinary(); // e.g., "1010101100110011..."

// Generate a color histogram hash
$colorHash = ColorHistogramHash::hashFromFile('/path/to/image.jpg');
echo $colorHash->toHex(); // e.g., "a1b2c3d4e5f6g7h8"

// Generate a MashedHash (comprehensive fingerprint)
$mHash = MashedHash::hashFromFile('/path/to/image.jpg');
echo $mHash->toHex(); // e.g., "1cf0e2a3b4596d87"

// Compare images
$hash1 = PerceptualHash::hashFromFile('/path/to/image1.jpg');
$hash2 = PerceptualHash::hashFromFile('/path/to/image2.jpg');
$distance = PerceptualHash::distance($hash1, $hash2);

if ($distance
