Acerca de Este Tutorial
PHP es un excelente lenguaje del lado del servidor para implementar algoritmos de encriptación y construir sistemas backend seguros. Este completo tutorial te guía en la implementación del cifrado César en PHP, desde funciones básicas hasta la integración con Laravel y endpoints de API RESTful. Ya sea que estés desarrollando herramientas educativas o aprendiendo conceptos criptográficos en un contexto backend, esta guía cubre todo lo que necesitas. Antes de sumergirte en el código, revisa nuestra Guía para Principiantes sobre el Cifrado César para comprender los fundamentos de la encriptación.
Entendiendo lo Básico
El cifrado César desplaza cada letra del texto plano un número fijo de posiciones en el alfabeto. En PHP, utilizaremos las funciones ord() y chr() junto con aritmética modular para implementar esto de manera eficiente en aplicaciones del lado del servidor y APIs.
Ejemplo:
Con un desplazamiento de 3, "HOLA" se convierte en "KROD"
Implementación Básica en PHP
Comencemos con una función de encriptación directa que demuestra el concepto principal:
<?php
/**
* Encrypts text using Caesar cipher with given shift value.
*
* @param string $text Text to encrypt
* @param int $shift Number of positions to shift (1-25)
* @return string Encrypted text
*/
function caesarEncrypt(string $text, int $shift): string
{
$result = '';
$textLength = strlen($text);
for ($i = 0; $i < $textLength; $i++) {
$char = $text[$i];
// Check if character is uppercase letter
if ($char >= 'A' && $char <= 'Z') {
// Shift within uppercase letters (A-Z)
$code = ord($char);
$char = chr((($code - 65 + $shift) % 26) + 65);
}
// Check if character is lowercase letter
elseif ($char >= 'a' && $char <= 'z') {
// Shift within lowercase letters (a-z)
$code = ord($char);
$char = chr((($code - 97 + $shift) % 26) + 97);
}
// Keep non-alphabetic characters unchanged
$result .= $char;
}
return $result;
}
// Example usage
$plaintext = "Hello World!";
$shift = 3;
$encrypted = caesarEncrypt($plaintext, $shift);
echo "Original: $plaintext\n";
echo "Encrypted: $encrypted\n";
// Output:
// Original: Hello World!
// Encrypted: Khoor Zruog!
Cómo Funciona la Implementación en PHP
Entendiendo las funciones clave de PHP utilizadas en el cifrado César:
Función ord()
Devuelve el valor ASCII de un carácter. Para 'A', ord('A')
devuelve 65. Esto es esencial para convertir letras en números para operaciones matemáticas.
Función chr()
Convierte valores ASCII de vuelta a caracteres. chr(65)
devuelve 'A'. Se utiliza para reconstruir la cadena cifrada después del desplazamiento.
Aritmética Modular (% 26)
El operador módulo hace que las letras den la vuelta en el alfabeto. Cuando 'Z' + 1 excede el alfabeto, vuelve a 'A'. Es crucial para mantener los límites alfabéticos.
Funciones de Cadenas
str_split()
, strlen()
y la concatenación de cadenas permiten un procesamiento eficiente del texto. PHP moderno también soporta funciones mb_*
para Unicode.
Implementación Moderna con PHP 8+
Utilizando características modernas de PHP incluyendo declaraciones de tipo, argumentos nombrados y expresiones match:
<?php
declare(strict_types=1);
/**
* Modern PHP 8+ Caesar cipher implementation
*/
function caesarCipher(string $text, int $shift): string
{
$shift = (($shift % 26) + 26) % 26; // Normalize shift
return implode('', array_map(
fn($char) => match(true) {
ctype_upper($char) => chr(((ord($char) - 65 + $shift) % 26) + 65),
ctype_lower($char) => chr(((ord($char) - 97 + $shift) % 26) + 97),
default => $char
},
str_split($text)
));
}
function caesarDecrypt(string $text, int $shift): string
{
return caesarCipher($text, -$shift);
}
// Example usage with modern features
$message = "PHP is powerful for backend development!";
$encrypted = caesarCipher($message, 7);
$decrypted = caesarDecrypt($encrypted, 7);
echo "Original: $message\n";
echo "Encrypted: $encrypted\n";
echo "Decrypted: $decrypted\n";
Integración con Laravel
Crea una clase de servicio Laravel para operaciones de cifrado César con inyección de dependencias y manejo adecuado de errores:
<?php
namespace App\Services;
/**
* Caesar Cipher Service for Laravel applications
*/
class CaesarCipherService
{
private int $shift;
public function __construct(int $shift = 3)
{
$this->setShift($shift);
}
/**
* Encrypt text using Caesar cipher
*/
public function encrypt(string $text): string
{
return $this->transform($text, $this->shift);
}
/**
* Decrypt text using Caesar cipher
*/
public function decrypt(string $text): string
{
return $this->transform($text, -$this->shift);
}
/**
* Transform text with given shift
*/
private function transform(string $text, int $shift): string
{
$result = '';
$shift = (($shift % 26) + 26) % 26;
foreach (str_split($text) as $char) {
if (ctype_upper($char)) {
$result .= chr(((ord($char) - 65 + $shift) % 26) + 65);
} elseif (ctype_lower($char)) {
$result .= chr(((ord($char) - 97 + $shift) % 26) + 97);
} else {
$result .= $char;
}
}
return $result;
}
/**
* Set new shift value
*/
public function setShift(int $shift): self
{
if ($shift < 0 || $shift > 25) {
throw new \InvalidArgumentException(
'Shift must be between 0 and 25'
);
}
$this->shift = $shift;
return $this;
}
/**
* Get current shift value
*/
public function getShift(): int
{
return $this->shift;
}
}
Construcción de un Endpoint API RESTful
Crea un controlador de API Laravel para exponer la funcionalidad del cifrado César a través de endpoints HTTP:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Services\CaesarCipherService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class CaesarCipherController extends Controller
{
public function __construct(
private CaesarCipherService $cipherService
) {}
/**
* Encrypt text using Caesar cipher
*
* @param Request $request
* @return JsonResponse
*/
public function encrypt(Request $request): JsonResponse
{
$validator = Validator::make($request->all(), [
'text' => 'required|string|max:10000',
'shift' => 'required|integer|min:1|max:25'
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors()
], 422);
}
try {
$this->cipherService->setShift($request->input('shift'));
$encrypted = $this->cipherService->encrypt(
$request->input('text')
);
return response()->json([
'success' => true,
'data' => [
'original' => $request->input('text'),
'encrypted' => $encrypted,
'shift' => $request->input('shift')
]
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Encryption failed: ' . $e->getMessage()
], 500);
}
}
/**
* Decrypt text using Caesar cipher
*
* @param Request $request
* @return JsonResponse
*/
public function decrypt(Request $request): JsonResponse
{
$validator = Validator::make($request->all(), [
'text' => 'required|string|max:10000',
'shift' => 'required|integer|min:1|max:25'
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors()
], 422);
}
try {
$this->cipherService->setShift($request->input('shift'));
$decrypted = $this->cipherService->decrypt(
$request->input('text')
);
return response()->json([
'success' => true,
'data' => [
'encrypted' => $request->input('text'),
'decrypted' => $decrypted,
'shift' => $request->input('shift')
]
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Decryption failed: ' . $e->getMessage()
], 500);
}
}
}
// routes/api.php
// Route::post('/caesar/encrypt', [CaesarCipherController::class, 'encrypt']);
// Route::post('/caesar/decrypt', [CaesarCipherController::class, 'decrypt']);
Implementación Avanzada Basada en Clases
Para aplicaciones en producción, un enfoque integral basado en clases proporciona mejor organización, validación y reutilización:
<?php
declare(strict_types=1);
/**
* Comprehensive Caesar Cipher implementation with advanced features
*/
class CaesarCipher
{
private int $shift;
private string $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
public function __construct(int $shift = 3)
{
$this->setShift($shift);
}
/**
* Encrypt text
*/
public function encrypt(string $text): string
{
return $this->transform($text, $this->shift);
}
/**
* Decrypt text
*/
public function decrypt(string $text): string
{
return $this->transform($text, -$this->shift);
}
/**
* Transform text with given shift
*/
private function transform(string $text, int $shift): string
{
$result = '';
$shift = (($shift % 26) + 26) % 26;
foreach (str_split($text) as $char) {
if (ctype_upper($char)) {
$result .= chr(((ord($char) - 65 + $shift) % 26) + 65);
} elseif (ctype_lower($char)) {
$result .= chr(((ord($char) - 97 + $shift) % 26) + 97);
} else {
$result .= $char;
}
}
return $result;
}
/**
* Brute force attack - try all possible shifts
*
* @param string $encryptedText Text to decrypt
* @return array All 26 possible decryptions
*/
public function bruteForce(string $encryptedText): array
{
$results = [];
for ($shift = 0; $shift < 26; $shift++) {
$results[] = [
'shift' => $shift,
'text' => $this->transform($encryptedText, -$shift)
];
}
return $results;
}
/**
* Encrypt/decrypt file contents
*/
public function processFile(
string $inputFile,
string $outputFile,
bool $encrypt = true
): bool {
if (!file_exists($inputFile)) {
throw new \RuntimeException("Input file not found");
}
$content = file_get_contents($inputFile);
$processed = $encrypt
? $this->encrypt($content)
: $this->decrypt($content);
return file_put_contents($outputFile, $processed) !== false;
}
/**
* Set shift value with validation
*/
public function setShift(int $shift): self
{
$this->shift = (($shift % 26) + 26) % 26;
return $this;
}
/**
* Get current shift value
*/
public function getShift(): int
{
return $this->shift;
}
/**
* ROT13 - Caesar cipher with shift of 13
*/
public static function rot13(string $text): string
{
return (new self(13))->encrypt($text);
}
/**
* Check if text is likely encrypted with Caesar cipher
*/
public function isLikelyEncrypted(string $text): bool
{
// Simple heuristic: check letter frequency distribution
$letterCount = preg_match_all('/[a-zA-Z]/', $text);
if ($letterCount === 0) {
return false;
}
// Count common English letters (E, T, A, O, I, N)
$commonLetters = preg_match_all('/[etaoinETAOIN]/', $text);
$ratio = $commonLetters / $letterCount;
// If ratio is very low, text might be encrypted
return $ratio < 0.3;
}
}
// Example usage
$cipher = new CaesarCipher(5);
// Encryption
$message = "PHP is great for backend development!";
$encrypted = $cipher->encrypt($message);
echo "Original: $message\n";
echo "Encrypted: $encrypted\n";
// Decryption
$decrypted = $cipher->decrypt($encrypted);
echo "Decrypted: $decrypted\n";
// Brute force attack
$mysteryText = "Mjqqt Btwqi";
echo "\nBrute force results:\n";
foreach (array_slice($cipher->bruteForce($mysteryText), 0, 5) as $result) {
echo "Shift {$result['shift']}: {$result['text']}\n";
}
// ROT13
$rot13Text = CaesarCipher::rot13("Hello World");
echo "\nROT13: $rot13Text\n";
Mejores Prácticas en PHP
Nuestra implementación sigue los estándares modernos de PHP y las mejores prácticas:
- Declaraciones de Tipo: Usa tipado estricto con
declare(strict_types=1)
para mayor seguridad en el código - Comentarios PHPDoc: Documentación clara que explica parámetros, tipos de retorno y excepciones
- Estándar de Codificación PSR-12: Sigue los estándares PHP-FIG para un estilo de código consistente
- Manejo de Errores: Usa excepciones para condiciones de error en lugar de códigos de retorno
- Validación de Entrada: Siempre valida y sanitiza la entrada del usuario, especialmente en contextos web
- Inyección de Dependencias: Usa el contenedor de servicios de Laravel para mayor capacidad de prueba
Errores Comunes a Evitar
Ten cuidado con estos errores comunes al implementar el cifrado César en PHP:
- Problemas de Codificación de Caracteres: Siempre usa codificación UTF-8 y considera las funciones
mb_*
para caracteres internacionales - Olvidar el Módulo: Sin % 26, los códigos de caracteres pueden exceder el rango ASCII válido
- No Normalizar el Desplazamiento: Maneja correctamente desplazamientos negativos y valores > 26
- Sensibilidad a Mayúsculas: Maneja letras mayúsculas y minúsculas con diferentes valores base (65 para A, 97 para a)
- Conceptos Erróneos de Seguridad: Nunca uses el cifrado César para seguridad real - es solo educativo
Uso por Línea de Comandos (CLI)
Los scripts PHP pueden ejecutarse desde la línea de comandos para procesamiento por lotes y automatización:
<?php
// caesar-cli.php - Command-line Caesar cipher tool
declare(strict_types=1);
require_once 'CaesarCipher.php';
function displayHelp(): void
{
echo <<<HELP
Caesar Cipher CLI Tool
Usage:
php caesar-cli.php [operation] [text] [shift]
Operations:
encrypt Encrypt the provided text
decrypt Decrypt the provided text
brute Try all shifts (brute force attack)
Examples:
php caesar-cli.php encrypt "Hello World" 3
php caesar-cli.php decrypt "Khoor Zruog" 3
php caesar-cli.php brute "Mjqqt Btwqi"
HELP;
}
// Parse command-line arguments
if ($argc < 2) {
displayHelp();
exit(1);
}
$operation = $argv[1] ?? '';
$text = $argv[2] ?? '';
$shift = isset($argv[3]) ? (int)$argv[3] : 3;
try {
$cipher = new CaesarCipher($shift);
switch ($operation) {
case 'encrypt':
if (empty($text)) {
throw new InvalidArgumentException('Text is required');
}
$result = $cipher->encrypt($text);
echo "Encrypted: $result\n";
break;
case 'decrypt':
if (empty($text)) {
throw new InvalidArgumentException('Text is required');
}
$result = $cipher->decrypt($text);
echo "Decrypted: $result\n";
break;
case 'brute':
if (empty($text)) {
throw new InvalidArgumentException('Text is required');
}
echo "Brute force results:\n";
foreach ($cipher->bruteForce($text) as $result) {
printf(
"Shift %2d: %s\n",
$result['shift'],
$result['text']
);
}
break;
default:
displayHelp();
exit(1);
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
exit(1);
}
Casos de Uso Prácticos
Las implementaciones del cifrado César en PHP son perfectas para:
Consideraciones de Rendimiento
La implementación tiene una complejidad temporal de O(n) donde n es la longitud del texto. Para un rendimiento óptimo en PHP:
- Usa
str_split()
y funciones de arrays en lugar de iteración carácter por carácter - Considera almacenar en caché los alfabetos cifrados para operaciones masivas
- Usa la extensión
mb_string
para el manejo de texto UTF-8 - Para archivos grandes, procesa en bloques para gestionar el uso de memoria
- Habilita OPcache en producción para el almacenamiento en caché de bytecode
- Performa con Xdebug o Blackfire para oportunidades de optimización
Probando Tu Implementación
Casos de prueba completos con PHPUnit para verificar que tu cifrado César funcione correctamente:
<?php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Services\CaesarCipherService;
class CaesarCipherTest extends TestCase
{
private CaesarCipherService $cipher;
protected function setUp(): void
{
$this->cipher = new CaesarCipherService(3);
}
/** @test */
public function it_encrypts_basic_text_correctly()
{
$this->assertEquals('DEF', $this->cipher->encrypt('ABC'));
}
/** @test */
public function it_handles_wrap_around_from_z_to_a()
{
$this->assertEquals('ABC', $this->cipher->encrypt('XYZ'));
}
/** @test */
public function it_preserves_case()
{
$this->assertEquals('Khoor', $this->cipher->encrypt('Hello'));
}
/** @test */
public function it_keeps_non_alphabetic_characters_unchanged()
{
$encrypted = $this->cipher->encrypt('Hello, World!');
$this->assertEquals('Khoor, Zruog!', $encrypted);
}
/** @test */
public function encryption_and_decryption_are_reversible()
{
$original = 'PHP Programming';
$encrypted = $this->cipher->encrypt($original);
$decrypted = $this->cipher->decrypt($encrypted);
$this->assertEquals($original, $decrypted);
}
/** @test */
public function it_handles_shift_of_zero()
{
$this->cipher->setShift(0);
$this->assertEquals('Test', $this->cipher->encrypt('Test'));
}
/** @test */
public function it_throws_exception_for_invalid_shift()
{
$this->expectException(\InvalidArgumentException::class);
$this->cipher->setShift(26);
}
/** @test */
public function it_handles_empty_string()
{
$this->assertEquals('', $this->cipher->encrypt(''));
}
/** @test */
public function it_handles_long_text()
{
$longText = str_repeat('ABC ', 1000);
$encrypted = $this->cipher->encrypt($longText);
$decrypted = $this->cipher->decrypt($encrypted);
$this->assertEquals($longText, $decrypted);
}
}
Ideas de Mejora
Extiende esta implementación con características adicionales:
Recursos Relacionados
Continúa tu viaje de aprendizaje en criptografía y PHP:
- Prueba nuestra Herramienta Interactiva de Cifrado César
- Aprende sobre el más seguro Cifrado Vigenère
- Explora ROT13, un caso especial con desplazamiento de 13
- Descubre técnicas para Romper el Cifrado César
- Ve implementaciones en JavaScript, Python, Java y C
Resumen
Has aprendido cómo implementar el cifrado César en PHP desde funciones básicas hasta la integración con Laravel y APIs RESTful. Cubrimos implementaciones clásicas, sintaxis moderna de PHP 8+, clases de servicio, endpoints de API y herramientas de línea de comandos. Este conocimiento forma la base para construir herramientas de encriptación más sofisticadas del lado del servidor y comprender la criptografía backend.
Practica creando tu propio servicio Laravel, construye una API completa con autenticación o experimenta con algoritmos de encriptación más complejos. Aunque el cifrado César no es adecuado para proteger datos sensibles, proporciona una excelente introducción a los conceptos criptográficos y la manipulación de cadenas en PHP para desarrolladores backend.