 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Mar 27 May, 2003 12:45 pm Asunto: Rutina de encriptación |
|
|
Se basa en un XOR binario y vale lo mismo para encriptar que para desencriptar. En C++ sólo me he encontrado con un problema, que es mínimo. Mientras en Clipper podía usar el conjunto de caracteres ASCII completo, en C++ (seguramente por el entorno Windows) sólo puedo usar los caracteres significativos (me parece recordar que los códigos ASCII del 32 al 127).
| Código: | AnsiString Encriptar(char *cVariable)
{
char aClave[6][6] = {"10000\0", "10101\0", "10010\0", "10011\0", "10001\0", "10001\0"};
AnsiString cCambio, cBin1, cBin2, cClave;
int nChar, nDato, nValor;
cCambio = "";
nDato = 0;
nChar = 0;
while (cVariable[nChar] ¡= NULL)
{
if (nDato > 5)
nDato = 0;
nValor = cVariable[nChar];
cBin1 = "";
cBin2 = "";
cClave = aClave[nDato];
while (nValor > 1)
{
cBin1 = IntToStr(nValor % 2) + cBin1;
nValor = INT(nValor / 2);
}
cBin1 = IntToStr(nValor) + cBin1;
if (cBin1.Length() > cClave.Length())
while (cClave.Length() < cBin1.Length())
cClave = "0" + cClave;
else
while (cBin1.Length() < cClave.Length())
cBin1 = "0" + cBin1;
for (int j = cClave.Length(); j > 0; j--)
cBin2 += cClave.SubString(j,1) ^ cBin1.SubString(j,1);
nValor = 0;
for (int j = cBin2.Length(); j > 0; j--)
nValor += StrToInt(cBin2.SubString(j,1)) * pow(2, (j - 1));
cCambio += CHAR(nValor);
nDato ++;
nChar ++;
}
return (cCambio);
} |
Explicandolo por partes.
Declaración de la función AnsiString Encriptar(char *cVariable)
La función devuelve un AnsiString; se le pasa el dato a encriptar en forma de un char.
Variables
char aClave[m][n] = {[...]};
AnsiString cCambio, cBin1, cBin2, cClave;
int nDato, nValor;
En aClave tenemos en formato binario la clave de encriptación, con una limitación: no pueden tener más de cinco bits (desde 00000 hasta 11111); con más bits me da resultados absurdos. Supongamos una clave como esta:
aClave[7][6] = {"10010\0","10011\0","10110\0", "11010\0","11011\0","10111\0","10101\0"};
cCambio es donde se va a guardar la cadena convertida. El resto de variables son campos de trabajo de la rutina.
nDato contiene la dimensión de aClave: cuantos elementos diferentes tiene el array; en este caso 7, y por lo tanto va desde 0 a 6.
El bucle principal (while) se controla con la longitud de la cadena a convertir, y trata la cadena letra por letra.
El primer paso del bucle es obtener el valor binario del código ASCII del carácter tratado ? while (nValor > 1) -. Previamente hemos asignado la clave que corresponda para trabajar (cClave). Una vez que tenemos el valor binario del carácter (cBin1), igualamos la longitud de este y la de cClave, añadiendo ceros a la izquierda hasta donde haga falta ( if (cBin1.Length() > cClave.Length())...).
Luego se hace la evaluacion XOR entre cBin1 y cClave y se guarda en cBin2. Sólo queda obtener el valor decimal de cBin2 y sacar el carácter que corresponde. Por ejemplo: si se convierte TOLEDO con estas definiciones (sólo la primera letra T):
cVariable = "TOLEDO\0"
cCambio = "";
nDato = 0;
nChar = 0;
INICIO
while (cVariable[nChar] ¡= NULL)
nValor = cVariable[0] » 84 (valor ASCII de T)
cClave = "10010" » Primer índice del array aClave
cBin1 = "1010100" » Después de ejecutar el bucle while (nValor > 1)
cClave = "0010010" » Después de if (cBin1.Length() > cClave.Length())
cBin2 = "0110001" » Después del bucle for (int j = cClave.Length(); j > 0; j--)
nValor = 70 » Después del bucle for (int j = cBin2.Length(); j > 0; j--)
cCambio = "F" » Carácter ASCII 70
Al terminar de ejecutarse la función, en la variable cCambio tendremos que TOLEDO vale F\\Z__X. La ventaja de esta función es que es ilimitada:
- Vale para "recomponer" el valor original sin más: si entra F\\Z__X, devuelve TOLEDO.
- Es infinita porque basta con poner más valores en el array aClave.
- Es muy difícil de reventar porque sólo el programador sabe los valores que pone en aClave, y cuanto más grande sea ese valor (número de elementos) más complicado reventarla. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
Fernando Diaz Master


Registrado: 18 Jul 2004Mensajes: 273Ubicación: Talavera de la Reina (Toledo)
|
Publicado: Mar 31 Ago, 2004 6:47 pm Asunto: |
|
|
He estado intentando convertir con tu metodo pero da error en algunas letras como Ç como puedo solucionarlo :S gracias (digo si hay algun método no if por cada letra y dejarla como estaba ...nose y esto me impide encriptar ejecutables o imagenes .... _________________ Los problemas mas dificiles tienen las soluciones mas sencillas
 |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Mie 01 Sep, 2004 8:10 am Asunto: |
|
|
Esta rutina la había escrito yo en principio en Clipper y me funcionaba bien con todo el rango de caracteres, pero al traspasarla a Builder me he encontardo que sólo funciona bien con el rango del caracteres ASCII del 32 (espacio blanco) al 127; la ç y la Ç están por encima de ese rango (135 y 128 respectivamente). _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
Fernando Diaz Master


Registrado: 18 Jul 2004Mensajes: 273Ubicación: Talavera de la Reina (Toledo)
|
Publicado: Mie 01 Sep, 2004 10:25 am Asunto: |
|
|
Y no se puede arreglar?, se podría hacer que esos caracteres no los cambie, eso se, pero si quisiera encriptarlos tambien sigiendo la clave....no hay alguna forma?....esque la verda esque el método que usas no lo entiendo muy bien _________________ Los problemas mas dificiles tienen las soluciones mas sencillas
 |
|
| Volver arriba |
|
 |
Fernando Diaz Master


Registrado: 18 Jul 2004Mensajes: 273Ubicación: Talavera de la Reina (Toledo)
|
Publicado: Jue 02 Sep, 2004 7:03 pm Asunto: |
|
|
Bien e modificado muy ligeramente la funcion de la siguiente forma para poder elegir la clave y para que un caracter fuera de rango no se altere y a la otra de encriptar texto funciona bastante bien pero ficheros exes....jpg... no y la forma de guardarlo creo que esta bien xk si ala ora de guardar pongo lo mismo que ha leido sin encriptarlo crea una copia exacta preo si guardo lo encriptado ya, una vez desencriptado despues no es igual ...nose
| Código: |
AnsiString Encriptar(char *cVariable)
{
char aClave[6][6];
sprintf(aClave[0],"%s\0",Form1->Edit1->Text.c_str());
sprintf(aClave[1],"%s\0",Form1->Edit2->Text.c_str());
sprintf(aClave[2],"%s\0",Form1->Edit3->Text.c_str());
sprintf(aClave[3],"%s\0",Form1->Edit4->Text.c_str());
sprintf(aClave[4],"%s\0",Form1->Edit5->Text.c_str());
sprintf(aClave[5],"%s\0",Form1->Edit6->Text.c_str());
AnsiString cCambio="", cBin1, cBin2, cClave;
int nChar=0, nDato=0, nValor;
while (cVariable[nChar] != NULL)
{
int x=cVariable[nChar];
if (x>=32&&x<=127)
{
if (nDato > 5)
nDato = 0;
nValor = cVariable[nChar];
cBin1="";
cBin2="";
cClave = aClave[nDato];
while (nValor > 1)
{
cBin1 = IntToStr(nValor % 2) + cBin1;
nValor = INT(nValor / 2);
}
cBin1 = IntToStr(nValor) + cBin1;
if (cBin1.Length() > cClave.Length())
while (cClave.Length() < cBin1.Length())
cClave = "0" + cClave;
else
while (cBin1.Length() < cClave.Length())
cBin1 = "0" + cBin1;
for (int j = cClave.Length(); j > 0; j--)
cBin2 += cClave.SubString(j,1) ^ cBin1.SubString(j,1);
nValor = 0;
for (int j = cBin2.Length(); j > 0; j--)
nValor += StrToInt(cBin2.SubString(j,1)) * pow(2, (j - 1));
cCambio += CHAR(nValor);
nDato ++;
nChar ++;
}
else
{
cCambio += cVariable[nChar];
nDato ++;
nChar ++;
}
}
return (cCambio);
}
|
_________________ Los problemas mas dificiles tienen las soluciones mas sencillas
 |
|
| Volver arriba |
|
 |
Fernando Diaz Master


Registrado: 18 Jul 2004Mensajes: 273Ubicación: Talavera de la Reina (Toledo)
|
Publicado: Vie 03 Sep, 2004 3:24 pm Asunto: |
|
|
se me olvido decir.... como lo areglo para que encripte tb exes y jpg?? _________________ Los problemas mas dificiles tienen las soluciones mas sencillas
 |
|
| Volver arriba |
|
 |
Lupo Ens

Registrado: 15 Ago 2005Mensajes: 30Ubicación: Prov, Buenos Aires - Argentina
|
Publicado: Mie 22 Feb, 2006 6:42 am Asunto: |
|
|
Gente, encontre una posible solucion para poder utilizar los caracteres menores a 32 y mayores a 127, el problema esta que cuando se utiliza algunos de estos caracteres (no se por que !!) el valor ascii pasa a ser negativo... Entonces lo que hice fue lo siguiente:
En la linea 13 de tu codigo, donde dice:
| Código: |
nValor = cVariable[nChar];
|
Le agregue esta condicion:
| Código: |
nValor = (int)cVariable[nChar];
if(nValor < 0)
nValor = 127 - nValor;
|
Y con eso parece que funciona bien.
Saludos _________________ Il Lupo |
|
| Volver arriba |
|
 |
XyVy Master


Registrado: 25 Ago 2002Mensajes: 557Ubicación: Murcia (España)
|
Publicado: Mie 22 Feb, 2006 9:07 am Asunto: |
|
|
Perdonadme quizás digo una tontería, pero se supone que si poneis char, aunque penseis que es un caracter al fin y al cabo es un valor entero comprendido entre -128 y 127, y si poneis unsigned char, tendreis un entero comprendido entre 0 y 255, la función xor no distingue entre caracteres y enteros, para la función todo son enteros, es decir internamente son números almacenados en simbolos del ordenador es decir 0's y 1's, lo único que hay que tener en cuenta es si la variable puede almacenar negativos o no, es decir, si se trata de un signed o unsigned...
Probad con unsigned char a ver que sucede...
Ciao. _________________ OJO!! Ya tenemos subforo de Bases de Datos!!
Gracias a los admins. |
|
| Volver arriba |
|
 |
Lupo Ens

Registrado: 15 Ago 2005Mensajes: 30Ubicación: Prov, Buenos Aires - Argentina
|
Publicado: Mie 22 Feb, 2006 11:17 pm Asunto: |
|
|
Esactamente XyVy !! diste en el clavo... declarando la variable como unsigned y dejando el codigo tal cual lo expuse Angel, ni hace falta verificar ninguna condicion como habia hecho yo...
Saludos y gracias por la idea !! _________________ Il Lupo |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Mie 19 Nov, 2008 3:02 am Asunto: |
|
|
amigos en que parte del codigo pongo la funcion para XoR no caigo, en un boton, en la unit.h donde...?
porfavor ayudenme _________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Mie 19 Nov, 2008 8:17 am Asunto: |
|
|
| ifrit escribió: | amigos en que parte del codigo pongo la funcion para XoR no caigo, en un boton, en la unit.h donde...?
porfavor ayudenme |
No está en ninguna parte; la función ES un XOR, no es que lo haya en ninguna parte tal operador lógico. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Sab 22 Nov, 2008 2:22 am Asunto: |
|
|
hola angel , se que he hablado mucho en este post pero no te imaginas la necesidad que te tengo de este codigo
bueno mi pregunta es como puedo cambiar a traves de codigo la clave de encriptacion es decir el [6][6]=10101/0 es decir los numeros para cambiar la clave de encriptacion
gracias _________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Sab 22 Nov, 2008 11:22 am Asunto: |
|
|
| ifrit escribió: | | bueno mi pregunta es como puedo cambiar a traves de codigo la clave de encriptacion es decir el [6][6]=10101/0 es decir los numeros para cambiar la clave de encriptacion |
En la definición
| Código: | char aClave[6][6] = {"10000\0", "10101\0", "10010\0", "10011\0", "10001\0", "10001\0"}; |
puedes poner las secuencias que quieras. Si te fijas bien sólo se trata de la transcripción binaria los código ASCII de la cadena:
| Cita: | aClave[0][6] = "10000\0" » ASCII 16
aClave[1][6] = "10101\0" » ASCII 21
etc. |
En ese array puedes poner los valores que quieras, como digo en la explicación del código, entre 00000 y 11111; la última posición (\0) es un cero binario para indicar el final de la cadena. Quiero decir que puedes usar un array que tenga 6, 7, 8 o las claves que quieras, ahora como también te digo, limitado a cinco posiciones ya que de otra forma salen resultados absurdos. Es decir, que podrías definir la clave así:
| Código: | aClave[8][6] = {"11001\0", "10011\0", "01001\0", "11001\0", "10001\0", "11000\0", "10101\0", "11111\0"}; |
o la que se te ocurra.
Lo de cambiarla a través de código sería tan sencillo como ir capturando valores decimales con un TEdit e ir guardándolos en un fichero de tipo ini por ejemplo, pero no te lo aconsejo porque de alguna forma tendrías que mandar el valor encriptado y la clave que has usado. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Sab 22 Nov, 2008 4:47 pm Asunto: |
|
|
muchas gracias por responderme angel mis respetos _________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|