fatkulnurk / radix-converter
Modern & Type-safe Radix (Base-N) Converter for PHP
Requires
- php: >=8.5
Requires (Dev)
- phpunit/phpunit: ^13.0
This package is auto-updated.
Last update: 2026-03-28 02:48:59 UTC
README
A type-safe library to convert numbers into short strings and back. Perfect for URL shorteners, unique IDs, and compact representations.
What Does This Do?
This library converts numbers like 12345 into short strings like "3d7" and back. This is useful for:
- Creating short URLs (like
bit.ly/3d7) - Generating compact unique IDs
- Making numbers easier to read and share
Installation
Run this command in your terminal:
composer require fatkulnurk/radix-converter
Requirements
- PHP 8.5 or higher
Quick Start
Here's the simplest way to use it:
<?php require_once 'vendor/autoload.php'; use Fatkulnurk\RadixConverter\ConverterFactory; use Fatkulnurk\RadixConverter\Enums\ConverterType; // Create a converter $converter = ConverterFactory::make(ConverterType::BASE62); // Convert number to string $encoded = $converter->encode(12345); echo $encoded; // Output: "3d7" // Convert string back to number $decoded = $converter->decode($encoded); echo $decoded; // Output: 12345
Available Converters
The library comes with 5 built-in converters:
| Name | Characters Used | Base | Example Output |
|---|---|---|---|
| BASE62 | Numbers + lowercase + uppercase | 62 | 3d7 |
| ALPHA_NUMERIC_UPPER | Numbers + uppercase letters | 36 | RS |
| ALPHA_NUMERIC_LOWER | Numbers + lowercase letters | 36 | rs |
| ALPHA_ONLY | Letters only (no numbers) | 52 | cU |
| HEX | Numbers + a-f | 16 | ff |
How Each Strategy Works
All converters extend AbstractBaseConverter which uses the radix (base-N) algorithm:
Encoding (number → string):
- Divide the number by the base
- Use the remainder to pick a character from the charset
- Repeat with the quotient until it becomes 0
- Read the result from last to first
Decoding (string → number):
- Start with 0
- For each character, multiply result by base and add the character's position value
- Return the final number
1. Base62 Strategy (Most Compact)
- Charset:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ(62 chars) - Base: 62
- Best for: URL shorteners, compact unique IDs
$converter = ConverterFactory::make(ConverterType::BASE62); $converter->encode(12345); // "3D7" $converter->decode("3D7"); // 12345
Example calculation for 12345:
- 12345 ÷ 62 = 199 remainder 7 → charset[7] = "7"
- 199 ÷ 62 = 3 remainder 13 → charset[13] = "D"
- 3 ÷ 62 = 0 remainder 3 → charset[3] = "3"
- Result: "3D7"
2. Alphanumeric Upper Strategy
- Charset:
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ(36 chars) - Base: 36
- Best for: Case-insensitive identifiers, easier to read
$converter = ConverterFactory::make(ConverterType::ALPHA_NUMERIC_UPPER); $converter->encode(1000); // "RS" $converter->decode("RS"); // 1000
3. Alphanumeric Lower Strategy
- Charset:
0123456789abcdefghijklmnopqrstuvwxyz(36 chars) - Base: 36
- Best for: Easy typing, lowercase-only systems
$converter = ConverterFactory::make(ConverterType::ALPHA_NUMERIC_LOWER); $converter->encode(1000); // "rs" $converter->decode("rs"); // 1000
4. Alpha Only Strategy
- Charset:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ(52 chars) - Base: 52
- Best for: When numbers must be excluded from identifiers
$converter = ConverterFactory::make(ConverterType::ALPHA_ONLY); $converter->encode(100); // "cU" $converter->decode("cU"); // 100
5. Hex Strategy (Custom)
- Charset:
0123456789abcdef(16 chars) - Base: 16
- Best for: Standard hexadecimal conversion
use Fatkulnurk\RadixConverter\CustomConverterRegistry; CustomConverterRegistry::register('hex', new \Fatkulnurk\RadixConverter\Strategies\HexStrategy()); $converter = CustomConverterRegistry::get('hex'); $converter->encode(255); // "ff" $converter->decode("ff"); // 255
Common Use Cases
1. URL Shortener
Convert database IDs into short codes for URLs:
$converter = ConverterFactory::make(ConverterType::BASE62); // Your database ID $databaseId = 154832; // Convert to short code $shortCode = $converter->encode($databaseId); // Result: "Ehi" // Create short URL $shortUrl = "https://yoursite.com/u/" . $shortCode; // Result: "https://yoursite.com/u/Ehi" // Later, get the original ID back $originalId = $converter->decode($shortCode); // Result: 154832
2. Different Converter Types
// Base62 (most compact) $base62 = ConverterFactory::make(ConverterType::BASE62); echo $base62->encode(1000); // "g8" // Uppercase only (easier to read) $upper = ConverterFactory::make(ConverterType::ALPHA_NUMERIC_UPPER); echo $upper->encode(1000); // "RS" // Lowercase only (easier to type) $lower = ConverterFactory::make(ConverterType::ALPHA_NUMERIC_LOWER); echo $lower->encode(1000); // "rs" // Letters only (no numbers) $alpha = ConverterFactory::make(ConverterType::ALPHA_ONLY); echo $alpha->encode(100); // "cU"
3. Error Handling
The library will throw errors if you try to:
- Encode negative numbers
- Decode empty strings
- Decode invalid characters
use Fatkulnurk\RadixConverter\Exceptions\ConverterException; try { $converter->encode(-5); } catch (ConverterException $e) { echo $e->getMessage(); // "Input number must be positive" } try { $converter->decode(''); } catch (ConverterException $e) { echo $e->getMessage(); // "Encoded value cannot be empty" } try { $converter->decode('abc!@#'); } catch (ConverterException $e) { echo $e->getMessage(); // "Invalid character found: !" }
Advanced: Custom Converters
You can create your own converter for any base system.
Using the Built-in Hex Converter
use Fatkulnurk\RadixConverter\CustomConverterRegistry; // Register the hex converter CustomConverterRegistry::register('hex', new \Fatkulnurk\RadixConverter\Strategies\HexStrategy()); // Use it $converter = CustomConverterRegistry::get('hex'); echo $converter->encode(255); // "ff" echo $converter->decode('ff'); // 255
Creating Your Own Converter
use Fatkulnurk\RadixConverter\Strategies\AbstractBaseConverter; use Fatkulnurk\RadixConverter\CustomConverterRegistry; // Create a binary (base-2) converter final readonly class BinaryStrategy extends AbstractBaseConverter { private const string CHARSET = '01'; protected function getCharset(): string { return self::CHARSET; } } // Register and use CustomConverterRegistry::register('binary', new BinaryStrategy()); $converter = ConverterFactory::make('binary'); echo $converter->encode(42); // "101010"
For Laravel Users
Laravel Octane / Swoole Warning
If you use Laravel Octane or Swoole, do NOT use CustomConverterRegistry because it keeps data between requests, which can cause problems.
Instead, use ConverterManager:
use Fatkulnurk\RadixConverter\ConverterManager; use Fatkulnurk\RadixConverter\Enums\ConverterType; // Create a manager $manager = new ConverterManager(); // Use it $encoded = $manager->encode(ConverterType::BASE62, 12345); $decoded = $manager->decode(ConverterType::BASE62, $encoded);
Using in Laravel Controllers
class MyController extends Controller { public function __construct( private ConverterManager $converterManager ) {} public function store(Request $request) { $code = $this->converterManager->encode(ConverterType::BASE62, 123); // ... } }
More Examples
The library includes example files you can run:
# Basic usage php examples/usage.php # Custom converters php examples/custom-strategy.php # Laravel Octane safety php examples/di-octane-safety.php
CI/CD
This project uses GitHub Actions for continuous integration. The workflow is configured in .github/workflows/ci.yml.
How It Works
The CI pipeline runs automatically on:
- Every push to
mainormasterbranches - Every pull request targeting
mainormasterbranches
Workflow Steps
| Step | Description |
|---|---|
| Checkout | Clones your code from GitHub |
| Setup PHP | Installs PHP 8.5 with required extensions |
| Install Dependencies | Runs composer install to get all packages |
| Run Tests | Executes PHPUnit tests via composer test |
Running Tests Locally
Before pushing your changes, run tests locally:
# Run all tests composer test # Run tests with coverage report composer test:coverage
Customizing the Workflow
To test on multiple PHP versions, edit .github/workflows/ci.yml:
strategy: matrix: php: ['8.5', '8.6'] # Add more versions here
License
MIT License - free to use in your projects.