Cambios que yo haría:
1. Reducir el ámbito de todas las variables
Así pasa que valor1...valor4 únicamente se usan en la segunda parte del algoritmo, no tiene sentido que estén declaradas al inicio de la función. Al inicio de la función únicamente deberían estar declaradas 1 variables: retval
2. Simplicar el tipo de las variables caracter no gana nada siendo
signed char. Lo cambio a
char. Con este cambio tonto consigo que esto:
se convierta en esto:
Con esto queda más claro que el bucle:
Código C++:
Ver originalif (caracter) {
do {
if (caracter == 0x1A)
break;
caracter = cadena[sizefilelic + 1];
++sizefilelic;
} while (caracter);
}
3. Traducir el codigo a cristiano
Se puede simplificar bastante, ya que lo único que hace es contar caracteres hasta llegar al caracter 0x1A o al final del string. La versión simplificada podría quedar tal que:
Código C++:
Ver originalchar* ptr;
for( *ptr = cadena ; *ptr && *ptr != 0x1A; ++ptr);
unsigned long sizefilelic = ptr - cadena;
Y con C++11 y lambdas:
Código C++:
Ver originalunsigned long sizefilelic = [cadena]()
{
char* ptr;
for( *ptr = cadena ; *ptr && *ptr != 0x1A; ++ptr);
return ptr - cadena;
}();
La segunda parte del algoritmo únicamente se ejecutará si
valor3 es distinto de 0... puesto que
valor3 coge su valor de
sizefilelic podemos hacer que esa parte se ejecute únicamente si el valor de esta última variable es distinto de 0... quedará un código un poco más legible:
Código C++:
Ver originalif( sizefilelic )
{
unsigned long contador = 0;
unsigned long valor2 = 0;
unsigned long valor3 = sizefilelic;
retval = valor3;
unsigned long valor4 = valor3 + 1;
do {
unsigned long valor1 = static_cast<unsigned long>(*reinterpret_cast<unsigned char*>(contador + reinterpret_cast<unsigned long>(cadena)));
valor2 = valor2 ^ valor1 + contador;
++contador;
valor3 = (*reinterpret_cast<unsigned char*>(valor2 % valor4 + reinterpret_cast<unsigned long>(cadena) + 1) + valor2 + (valor1 + valor2) * 2 + retval) * valor2;
retval = valor3;
} while (contador < sizefilelic);
}
Como el bucle do..while se va a ejecutar al menos una vez, la instrucción
retval=valor3 se puede eliminar con todo el cariño del mundo.
Código C++:
Ver originalvalor1 = static_cast<unsigned long>(*reinterpret_cast<unsigned char*>(contador + reinterpret_cast<unsigned long>(cadena)));
Esta línea lo único que hace es desplazarse un offset dado por
contador sobre el buffer
cadena... lo único que almacena
valor1 es el caracter existente en dicha posición convertido a unsigned long.
Un homólogo sencillo:
Código C++:
Ver originalvalor1 = static_cast<unsigned long>(cadena[contador]);
Esto:
Código C++:
Ver original*reinterpret_cast<unsigned char*>(valor2 % valor4 + reinterpret_cast<unsigned long>(cadena) + 1)
En cristiano significa esto:
Y para rematar la jugada, la variable
contador la podemos meter en un
for para sustituir el do-while, con lo que nos queda la segunda parte del algoritmo tal que:
Código C++:
Ver originalif( sizefilelic )
{
unsigned long valor2 = 0;
unsigned long valor3 = sizefilelic;
const unsigned long valor4 = valor3 + 1;
for( unsigned long contador=0; contador<sizefilelic; ++contador)
{
unsigned long valor1 = static_cast<unsigned long>(cadena[contador]);
valor2 = valor2 ^ valor1 + contador;
valor3 = (cadena[(valor2%valor4) + 1] + valor2 + (valor1 + valor2) * 2 + retval) * valor2;
retval = valor3;
}
}
No puedo probar el algoritmo primero porque no tengo ansistring y segundo porque no tengo cadenas de prueba... pero a grandes rasgos el código debería ser el mismo.
PD.: espero que si empiezas a sacar dinero de todo esto te acuerdes de mí jejejeje
Un saludo.