PHPackages                             robtimus/obfuscation - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. robtimus/obfuscation

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

robtimus/obfuscation
====================

Provides functionality for obfuscating text

1.0(6mo ago)00Apache-2.0PHPPHP &gt;=8.2CI passing

Since Nov 15Pushed 2mo agoCompare

[ Source](https://github.com/robtimus/php-obfuscation)[ Packagist](https://packagist.org/packages/robtimus/obfuscation)[ Docs](https://github.com/robtimus/php-obfuscation)[ RSS](/packages/robtimus-obfuscation/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (2)Used By (0)

Obfuscation
===========

[](#obfuscation)

[![Packagist Version](https://camo.githubusercontent.com/fce4d1fd7aba4dfbe680adfbedae7bd8863d49a00ad3e3e88e713c77de762a96/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f726f6274696d75732f6f62667573636174696f6e)](https://packagist.org/packages/robtimus/obfuscation)[![Build Status](https://github.com/robtimus/data-url/actions/workflows/build.yml/badge.svg)](https://github.com/robtimus/php-obfuscation/actions/workflows/build.yml)[![Quality Gate Status](https://camo.githubusercontent.com/31a2d8a7c6b3f253b460f227e59b38be497371889ab95a49ff788060d4a41b73/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d726f6274696d75732533416f62667573636174696f6e266d65747269633d616c6572745f737461747573)](https://sonarcloud.io/summary/overall?id=robtimus%3Aobfuscation)[![Coverage](https://camo.githubusercontent.com/f2b7042cc5a47df6616761af5c0aa59fc448e8de17498f26ebcda101d801abf2/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d726f6274696d75732533416f62667573636174696f6e266d65747269633d636f766572616765)](https://sonarcloud.io/summary/overall?id=robtimus%3Aobfuscation)

Provides functionality for obfuscating text. This can be useful for logging information that contains sensitive information.

Obfuscating strings
-------------------

[](#obfuscating-strings)

### Pre-defined obfuscators

[](#pre-defined-obfuscators)

The following pre-defined obfuscators are provided that all return an immutable obfuscator.

#### Obfuscate::all

[](#obfuscateall)

Replaces all characters with a mask character that defaults to `*`.

```
$obfuscator = Obfuscate::all();
$obfuscated = $obfuscator->obfuscateText('Hello World');
// $obfuscated is '***********'
```

Note: using this obfuscator still leaks out information about the length of the original text. One of the following two is more secure.

#### Obfuscate::fixedLength

[](#obfuscatefixedlength)

Replaces the entire text with a fixed number of the given mask character that defaults to `*`.

```
$obfuscator = Obfuscate::fixedLength(5);
$obfuscated = $obfuscator->obfuscateText('Hello World');
// $obfuscated is '*****'
```

#### Obfuscate::fixedValue

[](#obfuscatefixedvalue)

Replaces the entire text with a fixed value.

```
$obfuscator = Obfuscate::fixedValue('foo');
$obfuscated = $obfuscator->obfuscateText('Hello World');
// $obfuscated is 'foo'
```

#### Obfuscate::portion

[](#obfuscateportion)

While the above examples are simple, they are not very flexible. Using `Obfuscate::portion` you can build obfuscators that obfuscate only specific portions of text. Some examples:

##### Obfuscating all but the last 4 characters

[](#obfuscating-all-but-the-last-4-characters)

Useful for obfuscating values like credit card numbers.

```
$obfuscator = Obfuscate::portion()
    ->keepAtEnd(4)
    ->build();
$obfuscated = $obfuscator->obfuscateText('1234567890123456');
// $obfuscated is '************3456'
```

It’s advised to use `atLeastFromStart`, to make sure that values of fewer than 16 characters are still obfuscated properly:

```
$obfuscator = Obfuscate::portion()
    ->keepAtEnd(4)
    ->atLeastFromStart(12)
    ->build();
$obfuscated = $obfuscator->obfuscateText('1234567890');
// $obfuscated is '**********' and not '******7890'
```

##### Obfuscating only the last 2 characters

[](#obfuscating-only-the-last-2-characters)

Useful for obfuscating values like zip codes, where the first part is not as sensitive as the full zip code:

```
$obfuscator = Obfuscate::portion()
    ->keepAtStart(PHP_INT_MAX)
    ->atLeastFromEnd(2)
    ->build();
$obfuscated = $obfuscator->obfuscateText('SW1A 2AA');
// $obfuscated is 'SW1A 2**'
```

Here, the `keepAtStart` instructs the obfuscator to keep everything; however, `atLeastFromEnd` overrides that partly to ensure that the last two characters are obfuscated regardless of the value specified by `keepAtStart`.

##### Using a fixed length

[](#using-a-fixed-length)

Similar to using `Obfuscate::all`, by default an obfuscator built using `Obfuscate::portion` leaks out the length of the original text. If your text has a variable length, you should consider specifying a fixed total length for the result. The length of the result will then be the same no matter how long the input is:

```
$obfuscator = Obfuscate::portion()
    ->keepAtStart(2)
    ->keepAtEnd(2)
    ->withFixedTotalLength(6)
    ->build();
$obfuscated = $obfuscator->obfuscateText('Hello World');
// $obfuscated is 'He**ld'
$obfuscated = $obfuscator->obfuscateText('foo');
// $obfuscated is 'fo**oo'
```

Note that if `keepAtStart` and `keepAtEnd` are both specified, parts of the input may be repeated in the result if the input’s length is less than the combined number of characters to keep. This makes it harder to find the original input. For example, if in the example `foo` would be obfuscated into `fo***o` instead, it would be clear that the input was `foo`. Instead, it can now be anything that starts with `fo` and ends with `oo`.

### Obfuscate::none

[](#obfuscatenone)

Does not perform any obfuscation at all. It can be used as default to prevent checks. For instance:

```
$obfuscator = $somePossiblyUndefinedObfuscator ?: Obfuscate::none();
$obfuscated = $obfuscator->obfuscateText('Hello World');
// $obfuscated is 'Hello World' if $somePossiblyUndefinedObfuscator was null
```

### Obfuscate::exploded

[](#obfuscateexploded)

Explodes the text to an array, obfuscates each element, then implodes the array again.

```
$obfuscator = Obfuscate::exploded(', ', Obfuscate::fixedLength(3));
$obfuscated = $obfuscator->obfuscateText('a, b, c');
// $obfuscated is '***, ***, ***'
```

### Combining obfuscators

[](#combining-obfuscators)

Sometimes the obfucators in this library alone cannot perform the obfuscation you need. For instance, if you want to obfuscate credit cards, but keep the first and last 4 characters. If the credit cards are all fixed length, `Obfuscate::portion` can do just that:

```
$obfuscator = Obfuscate::portion()
    ->keepAtStart(4)
    ->keepAtEnd(4)
    ->build();
$obfuscated = $obfuscator->obfuscateText('1234567890123456');
// $obfuscated is '1234********3456'
```

However, if you attempt to use such an obfuscator on only a part of a credit card, you could end up leaking parts of the credit card that you wanted to obfuscate:

```
$incorrectlyObfuscated = $obfuscator->obfuscateText('12345678901234');
// $incorrectlyObfuscated is '1234******1234' where '1234********34' would probably be preferred
```

To overcome this issue, it’s possible to combine obfuscators. The form is as follows:

- Specify the first obfuscator, and the input length to which it should be used.
- Specify any other obfuscators, and the input lengths to which they should be used. Note that each input length should be larger than the previous input length.
- Specify the obfuscator that will be used for the remainder.

For instance, for credit card numbers of exactly 16 characters, the above can also be written like this:

```
$obfuscator = Obfuscate::none()->untilLength(4)
    ->then(Obfuscate::all())->untilLength(12)
    ->then(Obfuscate::none());
```

With this chaining, it’s now possible to keep the first and last 4 characters, but with at least 8 characters in between:

```
$obfuscator = Obfuscate::none()->untilLength(4)
    ->then(Obfuscate::portion()
        ->keepAtEnd(4)
        ->atLeastFromStart(8)
        ->build());
$obfuscated = $obfuscator->obfuscateText('12345678901234');
// $obfuscated is '1234********34'
```

### Splitting text during obfuscation

[](#splitting-text-during-obfuscation)

To make it easier to create obfuscators for structured text like email addresses, use a `SplitPoint`. Three implementations are provided :

- `atFirst(s)` splits at the first occurrence of string `s`.
- `atLast(s)` splits at the last occurrence of string `s`.
- `atNth(s, occurrence)` splits at the zero-based specified occurrence of string `s`.

For instance:

```
// Keep the domain as-is
$localPartObfuscator = Obfuscate::portion()
    ->keepAtStart(1)
    ->keepAtEnd(1)
    ->withFixedTotalLength(8)
    ->build();
$domainObfuscator = Obfuscate::none();
$obfuscator = SplitPoint::atFirst('@')->splitTo($localPartObfuscator, $domainObfuscator);
$obfuscated = $obfuscator->obfuscateText('test@example.org');
// $obfuscated is 't******t@example.org'
```

To obfuscate the domain except for the TLD, use a nested `SplitPoint`:

```
// Keep only the TLD of the domain
$localPartObfuscator = Obfuscate::portion()
    ->keepAtStart(1)
    ->keepAtEnd(1)
    ->withFixedTotalLength(8)
    ->build();
$domainObfuscator = SplitPoint::atLast('.')->splitTo(Obfuscate::all(), Obfuscate::none());
$obfuscator = SplitPoint::atFirst('@')->splitTo($localPartObfuscator, $domainObfuscator);
$obfuscated = $obfuscator->obfuscateText('test@example.org');
// $obfuscated is 't******t@*******.org'
```

#### Custom obfuscators

[](#custom-obfuscators)

To create a custom obfuscator, create a sub class of `Obfuscator`, override its constructor and implements its `obfuscateText` method. For instance:

```
$obfuscator = new class extends Obfuscator
{
    public function __construct()
    {
        parent::__construct();
    }

    public function obfuscateText(string $text): string
    {
        return strtoupper($text);
    }
};
$obfuscated = $obfuscator->obfuscateText('Hello World');
// $obfuscated is 'HELLO WORLD'
```

Obfuscating object properties
-----------------------------

[](#obfuscating-object-properties)

Use `PropertyObfuscator::builder` to start creating objects that can obfuscate single object properties as well as recursively all properties in an object or array.

The simplest form provides an obfucator for each property to obfuscate:

```
$propertyObfuscator = PropertyObfuscator::builder()
    ->withProperty('password', Obfuscate::fixedLength(3))
    ->build();
$obfuscatedPassword = $propertyObfuscator->obfuscateProperty('password', 'admin1234');
// $obfuscatedPassword is '***'
$obfuscatedUsername = $propertyObfuscator->obfuscateProperty('username', 'admin');
// $obfuscatedUsername is 'admin'
$object = new stdClass();
$object->username = 'admin';
$object->password = 'admin1234';
$obfuscatedObject = $propertyObfuscator->obfuscateProperties($object);
// $obfuscatedObject is a stdClass with properties username='admin' and password='***'
$obfuscatedArray = $propertyObfuscator->obfuscateProperties(array('username' => 'admin', 'password' => 'admin1234'));
// $obfuscatedArray is ['username' => 'admin', 'password' => '***']
```

This matches property names case sensitively, and for any nested objects or arrays will obfuscate any scalar property with the object's or array's obfuscator. This behaviour can be changed in two ways:

1. Per property. `withProperty` returns an object that can be used to further configure the property: ```
    $propertyObfuscator = PropertyObfuscator::builder()
        ->withProperty('password', Obfuscate::fixedLength(3), false) // defaults to true
            ->forObjects(PropertyObfuscationMode::EXCLUDE) // defaults to INHERIT
            ->forArrays(PropertyObfuscationMode::EXCLUDE) // defaults to INHERIT
        ->build();
    ```
2. Using global options: ```
    $propertyObfuscator = PropertyObfuscator::builder()
        ->caseInsensitiveByDefault() // defaults to case sensitive
        ->forObjectsByDefault(PropertyObfuscationMode::EXCLUDE) // defaults to INHERIT
        ->forArraysByDefault(PropertyObfuscationMode::EXCLUDE) // defaults to INHERIT
        ->withProperty('password', Obfuscate::fixedLength(3))
        ->build();
    ```

In both cases, `forObjects` and `forArrays` can take the following values:

- `PropertyObfuscationMode::SKIP` to skip obfuscating object or array values and all nested properties.
- `PropertyObfuscationMode::EXCLUDE` to not match properties with object or array values; nested properties will be matched separately.
- `PropertyObfuscationMode::INHERIT` to obfuscate each nested scalar property value or array element using the given obfuscator.
- `PropertyObfuscationMode::INHERIT_OVERRIDABLE` to obfuscate each nested scalar property value or array element using the given obfuscator; however, if a nested property has its own obfuscator defined this will be used instead.

Obfuscating HTTP headers
------------------------

[](#obfuscating-http-headers)

Use `HeaderObfuscator::builder` to start creating objects that can obfuscate single HTTP headers (as strings and string arrays) and associative arrays containing multiple headers. It's much like `PropertyObfuscator`, but like HTTP headers it's always case insensitive. Unlike `PropertyObfuscator`, it doesn't support nested objects, and for nested arrays each element is obfuscated separately. It also does not support skipping obfuscation.

```
$headerObfuscator = HeaderObfuscator::builder()
    ->withHeader('Authorization', Obfuscate::fixedLength(3))
    ->withHeader('Multiple-values', Obfuscate::exploded(', ', Obfuscate::fixedLength(3)))
    ->build();
$obfuscatedAuthorization = $headerObfuscator->obfuscateHeaderValue('authorization', 'Bearer someToken');
// $obfuscatedAuthorization is '***'
$obfuscatedAuthorizations = $headerObfuscator->obfuscateHeaderValues('authorization', array('Bearer someToken'));
// $obfuscatedAuthorizations is ['***']
$obfuscatedMultipleValues = $headerObfuscator->obfuscateHeaderValue('multiple-values', 'value1, value2, value3');
// $obfuscatedMultipleValues is '***, ***, ***'
$obfuscatedContentType = $headerObfuscator->obfuscateHeaderValue('Content-Type', 'application/json');
// $obfuscatedContentType is 'application/json'
$obfuscatedHeaders = $headerObfuscator->obfuscateHeaders(array(
    'authorization'   => 'Bearer someToken',
    'multiple-values' => 'value1, value2, value3',
    'content-type'    => 'application/json',
));
// $obfuscatedHeaders is ['authorization' => '***', 'multiple-values' => '***, ***, ***', 'content-type' => 'application/json']
```

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance77

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

184d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ae572a8816c41da92fcdc2c0f6296dde938ffc0bd81a99225ad3be6e057483de?d=identicon)[robtimus](/maintainers/robtimus)

---

Top Contributors

[![robtimus](https://avatars.githubusercontent.com/u/7405731?v=4)](https://github.com/robtimus "robtimus (28 commits)")

---

Tags

obfuscationphpphp8obfuscation

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/robtimus-obfuscation/health.svg)

```
[![Health](https://phpackages.com/badges/robtimus-obfuscation/health.svg)](https://phpackages.com/packages/robtimus-obfuscation)
```

###  Alternatives

[jenssegers/optimus

Id obfuscation based on Knuth's integer hash method

1.3k4.8M27](/packages/jenssegers-optimus)[delight-im/ids

Short, obfuscated and efficient IDs for PHP

289.5k1](/packages/delight-im-ids)[eve/dto

Simplistic, flexible Data Transfer Object library

1214.8k](/packages/eve-dto)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
