Generador de caracteres en Delphi

Iniciado por eb4bgr, 21 Enero 2009, 00:28 AM

0 Miembros y 1 Visitante están viendo este tema.

eb4bgr


Hola Hendrix,

Estoy actualizando y convirtiendo mis funciones para trabajar con el compilador Delphi-4.  Hace tiempo me pediste en un post que te enviara las funciones del generador de caracteres y ya he terminado  de actualizarlas.  Te envío el código fuente.

Los test de velocidad han mejorado un poco.  Por desgracia, su velocidad no resulta de mucha utilidad después de haber realizado tests más detallados.  Lo siento, no puedo conseguir más velocidad para estas funciones.

Características de las dos funciones...

KeyGen()  : Generador de caracteres utilizando los 256 elementos de la tabla ASCII.  Se pueden indicar las posiciones de inicio y final del generador.  Para todas las combinaciones posibles de 1 y 2 elementos de la tabla ASCII tarda en terminar...
- CPU Intel Pentium II Celerón a 433 MHz:  80 mSecs.
- CPU Intel Pentium IV a 900 MHz:  47 mSecs.
El límite teórico (depende de la RAM) para la longitud de la cadena de caracteres generada es el mismo del compilador, en este caso 2 GiB.  La versión anterior, hecha con el compilador xBasic 6.2.3, tardaba 310 mSecs. en realizar el mismo proceso.

KeyGenX()  : Generador de caracteres utilizando los elementos de la tabla ASCII que se deseen utilizar, desde 1 á 256 elementos.  Al igual que KeyGen(), también se pueden indicar las posiciones de inicio y final del generador.  Para todas las combinaciones posibles de 1 y 2 elementos de la tabla ASCII, indicando los 256 elementos, tarda en
terminar...
- CPU Intel Pentium II Celerón a 433 MHz:  1.643 Secs.
- CPU Intel Pentium IV a 900 MHz:  813 mSecs.
El límite teórico (depende de la RAM) para la longitud de la cadena de caracteres generada es el mismo del compilador, en este caso 2 GiB.  La versión anterior, hecha con el compilador xBasic 6.2.3, tardaba 17 SEGUNDOS en realizar el mismo proceso.



//> {String}
function KeyGen(nKeyLen: LongInt; cIn: string): string;
// KeyGen(): Generador de cadenas de caracteres.
// Desarrollo de la Funci¾n:  15-Ene-2009 > 16-Ene-2009
// (c) Alejandro Padrino, 2.009
//
// Funciones Relacionadas:
// - KeyGenX()
//
// nKeyLen     - Longitud mßxima de la cadena de caracteres.
// cIn         - Valor inicial de la cadena de caracteres.
//
// nBeginLen   - Longitud inicial de la cadena de caracteres.
// nCurrentLen - Longitud actual de la cadena de caracteres.
// lSw00       - Conmutador l¾gico.
// nTmp00      - Variable numÚrica temporal #00.
// nB00        - Variable numÚrica temporal #01.
//
// Esta funcion devuelve la combinacion de caracteres siguiente a la introducida
// por <cIn> usando los <256> caracteres de la tabla ASCII, con una longitud de
// <nKeyLen> caracteres.  Al alcanzarse la ultima combinacion de caracteres
// posible en la longitud indicada, esta funcion devuelve una cadena de
// caracteres vacia.
//
// AVISO IMPORTANTE:  Esta funcion puede reducir considerablemente la velocidad
//                    de su programa seg·n sea el valor de <nKeyLen>.  Si
//                    necesita trabajar con una tabla de caracteres programable
//                    utilice la funcion <KeyGenX()>.
//
// Ejemplo de uso:
//
// Function TestKeyGenSpeed(): Boolean;
// var
//  xGen, xLastGen: String;
//  Counter: Int64;
//  tBegin, tEnd: TDateTime;
//  nHours, nMinutes, nSeconds, nMilliSeconds: Word;
//  nKeyGenLength: LongInt;
//  lSw00: Boolean;
//
// Begin
//
//  lSw00 := False;
//  Counter := 0;
//  nKeyGenLength := 2;
//  tBegin := Time;
//  xGen := '';
//
// While (lSw00 <> True) Do Begin
//  xGen := KeyGen(nKeyGenLength, xGen);
//  Inc(Counter);
//  If (Length(xGen) > 0) Then xLastGen := xGen Else lSw00 := True;
// End;
//
//  tEnd := Time;
//  DecodeTime((tEnd - tBegin), nHours, nMinutes, nSeconds, nMilliSeconds);
//  ShowMessage('Needed time to all <' + IntToStr(Length(xLastGen)) + '> Byte combinations are:  <' +
//              + IntToStr(nHours) + '> Hours, <' + IntToStr(nMinutes) + '> Minutes, <' +
//              + IntToStr(nSeconds) + '> Seconds, <' + IntToStr(nMilliSeconds) +
//              + '> MilliSeconds.  Last value generated is <' + xLastGen +
//              + '>.  Total operations tested was <' + IntToStr(Counter - 1) + '>.');
//
//  Result := True;
//
// End;
//

var
nBeginLen: LongInt;
nCurrentLen: LongInt;
lSw00: Boolean;
nTmp00: Word;
nB00: LongInt;

begin

Result := '';
nKeyLen := Max(1, nKeyLen);
nBeginLen := Length(cIn);

if (nBeginLen > nKeyLen) then begin
Result := '';
Exit;
end;

nCurrentLen := Min(nKeyLen, nBeginLen);
nB00 := nCurrentLen;
lSw00 := True;

if (nBeginLen < 1) then begin
Result := #0;
Exit;
end;

while (nB00 > 0) do begin
if (lSw00 <> False) then begin
nTmp00 := ((Byte(cIn[nB00]) + 1) mod 256);
cIn[nB00] := Char(nTmp00);
if (nTmp00 < 1) then lSw00 := True else lSw00 := False;

if (nB00 = 1) and (lSw00 <> False) then begin
if (nBeginLen < nKeyLen) then Result := StringOfChar(#0, (nCurrentLen + 1)) else Result := '';
Exit;
end;
end;

Dec(nB00, 1);
end;

Result := cIn;

end;

//> {String}
function KeyGenX(nKeyLen: LongInt; cIn, cTable: string): string;
// KeyGenX(): Generador de cadenas de caracteres con tabla de caracteres programable.
// Desarrollo de la Funci¾n:  16-Ene-2009 > 20-Ene-2009
// (c) Alejandro Padrino, 2.009
//
// Funciones Relacionadas:
// - KeyGen()
//
// nKeyLen     - Longitud mßxima de la cadena de caracteres.
// cIn         - Valor inicial de la cadena de caracteres.
// cTable      - Caracteres ASCII para usar en el generador, indicados en orden ascendente.
//
// aCh[]       - Array de elementos ASCII.
// aTable[]    - Array de caracteres del generador.
// nBeginLen   - Longitud inicial de la cadena de caracteres.
// nCurrentLen - Longitud actual de la cadena de caracteres.
// lSw00       - Conmutador l¾gico.
// nTmp00      - Variable numÚrica temporal #00.
// nTmp01      - Variable numÚrica temporal #01.
// nB00        - Variable numÚrica temporal #02.
// nB01        - Variable numÚrica temporal #03.
//
// Esta funcion devuelve la combinacion de caracteres siguiente a la introducida
// por <cIn> usando los caracteres de la tabla ASCII indicados en <cTable>, con una
// longitud de <nKeyLen> caracteres.  Al alcanzarse la ultima combinacion de caracteres
// posible en la longitud indicada, esta funcion devuelve una cadena de caracteres vacia.
//
// Si no se indica la tabla de caracteres <cTable>, o la cadena de entrada <cIn> estß
// fuera del rango, esta funci¾n devolverß una cadena de caracteres vacÝa.  La cadena de
// caracteres devuelta por esta funci¾n se generarß seg·n el ¾rden en que se indiquen
// los caracteres en el parßmetro <cTable>.
//
// AVISO IMPORTANTE:  Esta funcion puede reducir considerablemente la velocidad
//                    de su programa seg·n sea el valor de <nKeyLen>.  Si necesita
//                    trabajar con los <256> caracteres de la tabla ASCII utilice
//                    la funcion <KeyGen()>, es mucho mßs rßpida.
//
// Ejemplo de uso:
//
// Function TestKeyGenXSpeed(): Boolean;
// var
//  xGen, xCharGen, xLastGen: String;
//  Counter: Int64;
//  tBegin, tEnd: TDateTime;
//  nHours, nMinutes, nSeconds, nMilliSeconds: Word;
//  nKeyGenLength: LongInt;
//  lSw00: Boolean;
//
// Begin
//
//  lSw00 := False;
//  Counter := 0;
//  nKeyGenLength := 4;
//  tBegin := Time;
//  xCharGen := '0123456789';
//  xGen := '';
//
// While (lSw00 <> True) Do Begin
//  xGen := KeyGenX(nKeyGenLength, xGen, xCharGen);
//  Inc(Counter);
//  If (Length(xGen) > 0) Then xLastGen := xGen Else lSw00 := True;
// End;
//
//  tEnd := Time;
//  DecodeTime((tEnd - tBegin), nHours, nMinutes, nSeconds, nMilliSeconds);
//  ShowMessage('Needed time to all <' + IntToStr(Length(xLastGen)) + '> Byte combinations using <' +
//              + xCharGen + '> characters are:  <' + IntToStr(nHours) + '> Hours, <' +
//              + IntToStr(nMinutes) + '> Minutes, <' + IntToStr(nSeconds) + '> Seconds, <' +
//              + IntToStr(nMilliSeconds) + '> MilliSeconds.  Last value generated is <' + xLastGen +
//              + '>.  Total operations tested was <' + IntToStr(Counter - 1) + '>.');
//
//  Result := True;
//
// End;
//

var
aCh: array of SmallInt;
aTable: array of Byte;
nBeginLen: LongInt;
nCurrentLen: LongInt;
lSw00: Boolean;
nTmp00: SmallInt;
nTmp01: SmallInt;
nB00: LongInt;
nB01: LongInt;

begin

Result := '';
nKeyLen := Max(1, nKeyLen);
nBeginLen := Length(cIn);

if (nBeginLen > nKeyLen) or (Length(cTable) < 1) then begin
Result := '';
Exit;
end;

SetLength(aCh, 256);
SetLength(aTable, (Length(cTable) + 1));
nCurrentLen := 0;
nB00 := 1;

while (nB00 <= Length(cTable)) do begin
nTmp00 := Byte(cTable[nB00]);

if (aCh[nTmp00] >= 0) then begin
Inc(nCurrentLen, 1);
aTable[nCurrentLen] := nTmp00;
aCh[nTmp00] := (-1);
end;

Inc(nB00, 1);
end;

SetLength(aTable, (nCurrentLen + 1));
nCurrentLen := Min(nKeyLen, nBeginLen);
nB00 := nCurrentLen;
lSw00 := True;

if (nBeginLen < 1) then begin
Result := Char(aTable[1]);
Exit;
end;

while (nB00 > 0) do begin
nTmp00 := Byte(cIn[nB00]);
nTmp01 := (-1);
nB01 := 1;

while (nB01 < Length(aTable)) do begin
if (nTmp00 = aTable[nB01]) then begin
nTmp01 := (nB01 + 1);
Break;
end;

Inc(nB01, 1);
end;

if (nTmp01 < 0) then begin
Result := '';
Exit;
end

else if (lSw00 <> False) then begin
lSw00 := False;

if (nTmp01 >= Length(aTable)) then begin
nTmp01 := 1;
lSw00 := True;
end;

nTmp00 := aTable[nTmp01];
cIn[nB00] := Char(nTmp00);

if (nB00 = 1) and (lSw00 <> False) then begin
if (nBeginLen < nKeyLen) then Result := StringOfChar(Char(aTable[1]), (nCurrentLen + 1)) else Result := '';
Exit;
end;
end;

Dec(nB00, 1);
end;

Result := cIn;

end;



Un saludo a todos.

galess

hola que tal, que hace MAX y que hace MIN ?

eb4bgr

Son funciones estándar en la mayoría de los compiladores.  Devuelven el valor máximo o mínimo de los números indicados.