PHPackages                             omaressaouaf/text-morph - 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. omaressaouaf/text-morph

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

omaressaouaf/text-morph
=======================

A lightweight PHP package for reversible text transformations using simple morphing algorithms and a composable pipeline

v1.0.0(today)10MITPHPPHP ^8.4CI passing

Since Jun 26Pushed todayCompare

[ Source](https://github.com/omaressaouaf/text-morph)[ Packagist](https://packagist.org/packages/omaressaouaf/text-morph)[ Docs](https://github.com/omaressaouaf/text-morph)[ RSS](/packages/omaressaouaf-text-morph/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (2)Versions (2)Used By (0)

TextMorph
=========

[](#textmorph)

[![Latest Stable Version](https://camo.githubusercontent.com/1c85aedaa8f0d31aba99a7312919e48b322ca516cb892db2ee7799ca6f5e05b2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f6d6172657373616f7561662f746578742d6d6f7270682e737667)](https://packagist.org/packages/omaressaouaf/text-morph)[![License](https://camo.githubusercontent.com/3845b28b068b080366fbbd83a7cc82fc8b7eb89ffcbdb33e728aef933a49afb9/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6f6d6172657373616f7561662f746578742d6d6f727068)](LICENSE)[![Tests](https://github.com/omaressaouaf/text-morph/actions/workflows/tests.yml/badge.svg)](https://github.com/omaressaouaf/text-morph/actions/workflows/tests.yml)

A lightweight PHP package for **reversible text transformations** using simple morphing algorithms and a composable pipeline.

Features
--------

[](#features)

- **Rotational** morphing: shift letters across a 52-character alphabet with wrap-around
- **Substitution** morphing: bidirectional character-pair swaps with case preservation
- **Transposition** morphing: rail-fence (zigzag) character reordering
- **Composite** pipeline: chain multiple morphers and reverse them in one call
- Every morpher supports `morph()` and `unmorph()`
- Framework-agnostic, zero runtime dependencies

> TextMorph is a text transformation package. It is not intended for encryption, password hashing, or security-sensitive data. It currently operates on ASCII strings. Multibyte/Unicode-aware transformations are not currently supported.

---

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

[](#installation)

Install via Composer:

```
composer require omaressaouaf/text-morph
```

---

Usage
-----

[](#usage)

Every morpher implements the `TextMorpher` contract:

```
use Omaressaouaf\TextMorph\Contracts\TextMorpher;

interface TextMorpher
{
    public function morph(string $text): string;

    public function unmorph(string $text): string;
}
```

### Rotational Morphing

[](#rotational-morphing)

Shift each letter forward across `a-zA-Z`, wrapping from `Z` back to `a`. Non-alphabetic characters are left unchanged.

```
use Omaressaouaf\TextMorph\Morphers\RotationalTextMorpher;

$morpher = new RotationalTextMorpher(3);

$morphed = $morpher->morph('Meet at 9pm!');
// Phhw dw 9sp!

$original = $morpher->unmorph($morphed);
// Meet at 9pm!
```

More examples:

```
$morpher = new RotationalTextMorpher(1);

$morpher->morph('a'); // b
$morpher->morph('z'); // B
$morpher->morph('Z'); // a
```

### Substitution Morphing

[](#substitution-morphing)

Swap character pairs bidirectionally. Each pair defines a two-way substitution that preserves letter case.

```
use Omaressaouaf\TextMorph\Morphers\SubstitutionTextMorpher;

$morpher = new SubstitutionTextMorpher(['ab', 'cd']);

$morpher->morph('aabbcc'); // bbaacc
$morpher->morph('adam');   // bcbm
```

Because pairs are swaps, `unmorph()` applies the same transform as `morph()`:

```
$morpher->unmorph('bbaacc'); // aabbcc
```

### Transposition Morphing

[](#transposition-morphing)

Reorder characters using a rail-fence (zigzag) cipher. Letters are written in a zigzag across the configured number of rails, then read row by row.

```
use Omaressaouaf\TextMorph\Morphers\TranspositionTextMorpher;

$morpher = new TranspositionTextMorpher(3);

$morpher->morph('HELLO');       // HOELL
$morpher->morph('Meet at 9pm!'); // M 9eta p!etm
```

`unmorph()` splits the text back into rails and reads the zigzag to restore the original order.

### Composite Pipeline

[](#composite-pipeline)

Chain multiple morphers together. `morph()` applies them in registration order; `unmorph()` reverses them.

```
use Omaressaouaf\TextMorph\Morphers\CompositeTextMorpher;
use Omaressaouaf\TextMorph\Morphers\RotationalTextMorpher;
use Omaressaouaf\TextMorph\Morphers\SubstitutionTextMorpher;
use Omaressaouaf\TextMorph\Morphers\TranspositionTextMorpher;

$pipeline = new CompositeTextMorpher();

$pipeline->add(new SubstitutionTextMorpher(['ae', 'io']));
$pipeline->add(new RotationalTextMorpher(5));
$pipeline->add(new TranspositionTextMorpher(3));

$original = 'Meet at 9pm!';

$morphed = $pipeline->morph($original);
$restored = $pipeline->unmorph($morphed);

// $restored === $original
```

---

### Custom Morphers

[](#custom-morphers)

The package is fully extensible. You can create your own morphers by implementing the `TextMorpher` contract.

#### Example

[](#example)

```
namespace App\Morphers;

use Omaressaouaf\TextMorph\Contracts\TextMorpher;

class ReverseTextMorpher implements TextMorpher
{
    public function morph(string $text): string
    {
        return strrev($text);
    }

    public function unmorph(string $text): string
    {
        return strrev($text);
    }
}
```

Then use it on its own or inside a composite pipeline:

```
use App\Morphers\ReverseTextMorpher;
use Omaressaouaf\TextMorph\Morphers\CompositeTextMorpher;
use Omaressaouaf\TextMorph\Morphers\RotationalTextMorpher;

$pipeline = new CompositeTextMorpher();
$pipeline->add(new ReverseTextMorpher());
$pipeline->add(new RotationalTextMorpher(13));

$morphed = $pipeline->morph('Hello');
$original = $pipeline->unmorph($morphed);
```

This approach allows you to implement completely custom transformations while preserving the same architecture and developer experience as the package's built-in morphers.

---

Testing
-------

[](#testing)

Run unit tests:

```
composer test
```

---

License
-------

[](#license)

This package is licensed under the [MIT License](https://github.com/omaressaouaf/text-morph/blob/master/LICENSE).

###  Health Score

42

—

FairBetter than 89% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

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

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/80538867?v=4)[Omar Essaouaf](/maintainers/omaressaouaf)[@omaressaouaf](https://github.com/omaressaouaf)

---

Top Contributors

[![omaressaouaf](https://avatars.githubusercontent.com/u/80538867?v=4)](https://github.com/omaressaouaf "omaressaouaf (26 commits)")

---

Tags

algorithmsencodingencoding-algorithmsencoding-decodingphptext-morphtext-transformationphpomaressaouaftext-transformationtext-morphtext-encodingtext-decodingencoding-algorithmsdecoding-algorithms

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/omaressaouaf-text-morph/health.svg)

```
[![Health](https://phpackages.com/badges/omaressaouaf-text-morph/health.svg)](https://phpackages.com/packages/omaressaouaf-text-morph)
```

###  Alternatives

[omaressaouaf/laravel-id-generator

Generate custom incremental unique ids for Laravel

577.1k](/packages/omaressaouaf-laravel-id-generator)[imanghafoori/laravel-anypass

A minimal yet powerful package to help you in development.

21422.6k](/packages/imanghafoori-laravel-anypass)

PHPackages © 2026

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