El cifrado PC1 no es muy conocido, al menos yo nunca había oído hablar de el hasta hace poco. Lo poco que he podido encontrar en Internet sobre el es que fue desarrollado por un tal Alexander PUKALL en el año 1991 y algo de código en C y pascal. El algoritmo tiene una longitud de clave de 128 bits (16 bytes) y tiene como particularidad que el texto cifrado esta compuesto solamente por caracteres de la 'a' a la 'p' por lo que es muy sencillo guárdalo como texto al no aparecer caracteres extraños.
No se si es un buen sistema de cifrado o no, al no encontrar mucha información al respecto en internet, mi unico interés por el viene de que una aplicación con la trabajo habitualmente guarda sus contraseña utilizando este cifrado, así que me he decidido a hacer este pequeño código para poder trabajar con esas contraseñas.
Si a alguien más le resulta útil que lo utilice.
unit Pukall; interface uses SysUtils; function Cifrar(Texto, Clave: AnsiString): AnsiString; function Descifrar(Texto, Clave: AnsiString): AnsiString; implementation type TPukallContext = record dx: Word; si: Word; Key: array[0..15] of AnsiChar; end; procedure Swap(var W1: Word; var W2: Word); var W: Word; begin W:= W1; W1:= W2; W2:= W; end; function Assemble(var Context: TPukallContext): Word; var i: Integer; ax, bx, cx: Word; x1a0: array[0..7] of Word; begin with Context do begin Result:= 0; for i:= 0 to 7 do begin if i = 0 then x1a0[0]:= (ord(Key[0]) shl 8) + ord(Key[1]) else x1a0[i]:= x1a0[i-1] xor ( ( ord(Key[i*2]) shl 8) + ord(Key[(i*2)+1]) ); // "Code" block dx:= dx+i; ax:= x1a0[i]; cx:= $015a; bx:= $4e35; Swap(ax,si); Swap(ax,dx); if (ax <> 0) then ax:= ax*bx; Swap(ax,cx); if (ax <> 0) then begin ax:= ax*si; inc(cx,ax); end; Swap(ax,si); ax:= ax*bx; inc(dx,cx); inc(ax); x1a0[i]:= ax; // End of "Code" block Result:= Result xor ax xor dx; end; end; end; function Cifrar(Texto, Clave: AnsiString): AnsiString; var b: Byte; i, j, k: Integer; Context: TPukallContext; begin Result:= ''; // Si no hay nada que cifrar salimos if Length(Texto) < 0 then Exit; // Inicializamos las variables FillChar(Context,Sizeof(Context),#0); with Context do begin // Copiamos la clave StrLCopy(Key, PAnsiChar(Clave), 16); // Para cada elemento de la cadena for i:= 1 to Length(Texto) do begin b:= Ord(Texto[i]); // Ciframos este byte k:= Assemble(Context); // Cambiamos la clave a partir del byte antes de cifrar for j:= 0 to 15 do Key[j]:= AnsiChar(Ord(Key[j]) xor b); // Guardamos el resultado b:= b xor (k shr 8) xor (k and $FF); Result:= Result + AnsiChar( Ord('a') + (b shr 4) ) + AnsiChar( Ord('a') + (b and $0F) ); end; end; end; function Descifrar(Texto, Clave: AnsiString): AnsiString; var b: Byte; i, j, k: Integer; Context: TPukallContext; begin Result:= ''; // Si la longitud del texto no es multiplo de 2 salimos if Odd(Length(Texto)) then Exit; // Inicializamos las variables FillChar(Context,Sizeof(Context),#0); with Context do begin // Copiamos la clave StrLCopy(Key, PAnsiChar(Clave), 16); // Tomamos los elementos de dos en dos for i:= 0 to (Length(Texto) div 2) - 1 do begin // Recomponemos el byte a partir de los caracteres b:= ((Ord(Texto[(2*i)+1])-Ord('a')) shl 4) + (Ord(Texto[(2*i)+2])-Ord('a')); // Desciframos este byte k:= Assemble(Context); b:= b xor (k shr 8) xor (k and $FF); Result:= Result + AnsiChar(b); // Modificamos la clave a partir del byte descifrado for j:= 0 to 15 do Key[j]:= AnsiChar(Ord(Key[j]) xor b); end; end; end; end.
Ejemplo de como usarlo:
var Str: String; begin Str:= Cifrar('Hola mundo','Clave'); Writeln('Texto cifrado: ' + Str); Str:= Descifrar(Str,'Clave'); Writeln('Texto descifrado: ' + Str); end.
El ejemplo anterior da una salida como esta:
Texto cifrado: agcjjacjmhnibkjajjgi Texto descifrado: Hola mundo
Comentarios
Me lo guardo :) Saludos.
Me lo guardo :)
Saludos.
Interesante...
Interesante...
Gracias por compartirlo, tal vez lo use.
Saludos.