Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Rutina de encriptación
Ir a página 1, 2  Siguiente
 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Tips & Tricks
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Rutina de encriptación Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado MSN Messenger
Mensaje    Asunto: Responder citando

¡Vale! ¡Collejas variadas!

Xyvy: tienes toda la razón. Esa es la solución. ¿Cómo no se me ha ocurrido?
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

muchas gracias por responderme angel mis respetos
_________________
Todos somos ignorantes, lo que no todos ignoramos lo mismo...
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mostrar mensajes de anteriores:   
Cambiar a:  
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


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.