Avatar billede blizim Nybegynder
06. maj 2005 - 01:26 Der er 37 kommentarer og
1 løsning

Kryptering med billed som key

Hejsa..
Jeg står i et lille dilemma, jeg vil lave en kryptering hvor jeg har et .txt dokument som skal krypteres. Har selv rodet med XOR kryptering hvilket er simpelt og latterligt. Så kunen godt tænke mig at kryptere det med et billed. Ved bare ikke just hvordan, så håbede en eller anden kunne hjælpe mig.. Gerne encrypt og decrypt, og skal være i c++ :)

På forhånd tak.

ps. er ikke alt for god til C++ :S
Avatar billede arne_v Ekspert
06. maj 2005 - 09:29 #1
Flere måder:
  - læse alle bytes fra billede og bruge det som key (XOR eller +)
  - lave en MD5 af billede og bruge det som key til en kendt algoritme
    som f.eks. DES/3DES/AES
  - gemme din tekst i billedet som "støj"
Avatar billede blizim Nybegynder
06. maj 2005 - 15:52 #2
okay, er allerede lost :) tror bare jeg skal starte med at forske videre med XOR, synes det er en dårlig algoritme men hvad fanden... Jeg havde nemlig nogle problemer med det.. jeg kan godt finde ud af at gøre det med f.eks. a xor b, forstår hvad der sker osv. Dog hvis jeg vil f.eks. vil have a til at være en tekstfil med et tekststykke i som skal krypteres med hensyn til ordet "kaffe". Altså hvis der står "hej med dig" i tekstfilen. Så tager den: A xor k, l xor a, j xor f, mellemrum xor f, m xor e, e xor k, osv... Hvordan gør jeg det?

hvis du kunne ligge et eksempel ville jeg blive glad. :)
Avatar billede arne_v Ekspert
06. maj 2005 - 15:53 #3
arrays !

jeg finder lige et eksempel
Avatar billede blizim Nybegynder
06. maj 2005 - 15:54 #4
takker.. så må jeg se om jeg kan få det til at virke :)
Avatar billede arne_v Ekspert
06. maj 2005 - 15:55 #5
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
  int i;
  char plain[] = "Dette er en lille test";
  char key[] = "TBFRGFARFM";
  char *cipher;
  int l = strlen(plain);
  cipher = (char *)malloc(l);
  for(i=0;i<l;i++) cipher[i] = plain[i] ^ key[i % strlen(key)];
  cipher[l] = '\0';
  printf("%s -> %s\n",plain,cipher);
  for(i=0;i<l;i++) plain[i] = cipher[i] ^ key[i % strlen(key)];
  plain[l] = '\0';
  printf("%s -> %s\n",cipher,plain);
}
Avatar billede arne_v Ekspert
06. maj 2005 - 15:56 #6
koden er ikke pæn bl.a. er der ingen garanti for a cipher arrayet er printable !

Men:

cipher[i] = plain[i] ^ key[i % strlen(key)];

er god nok.
Avatar billede arne_v Ekspert
06. maj 2005 - 15:58 #7
Men check lige den her:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define N 1000000
#define MAXKEYLEN 20

int freq[20][256];

char find_key_char(unsigned char *s, int l, int ix,int lkey)
{
  int j,k,maxval,maxix;
  memset(freq,0,sizeof(freq));
  for(j=0;j<l;j++) freq[j%lkey][s[j]]++;
  maxix=-1;
  maxval=0;
  for(k=0;k<256;k++)
  {
      if(freq[ix][k]>maxval)
      {
        maxix=k;
        maxval=freq[ix][k];
      }
  }
  return maxix^' ';
}
void analyse(unsigned char *s, int l,char *key)
{
  int i,j,k,maxval,maxix;
  double sum,xl;
  for(i=1;i<MAXKEYLEN;i++)
  {
      memset(freq,0,sizeof(freq));
      for(j=0;j<l;j++) freq[j%i][s[j]]++;
      xl=l/i;
      sum=0;
      for(k=0;k<256;k++) sum+=(freq[0][k]/xl)*(freq[0][k]/xl);
      if(sum>0.05)
      {
        for(j=0;j<i;j++)
        {
            maxix=-1;
            maxval=0;
            for(k=0;k<256;k++)
            {
              if(freq[j][k]>maxval)
              {
                  maxix=k;
                  maxval=freq[j][k];
              }
            }
            key[j]=maxix^' ';
        }
        key[i]='\0';
        return;
      }
  }
}

int main(int argc, char *argv[])
{
  int i,j,l,lkey;
  char key[80];
  char *plain, *cipher;
  FILE *fp1,*fp2;
  cipher=(char *)malloc(N);
  fp1=fopen(argv[1],"rb");
  l=fread(cipher,1,N,fp1);
  fclose(fp1);
  analyse(cipher,l,key);
  printf("%s\n",key);
  plain = (char *)malloc(l);
  for(i=0;i<l;i++) plain[i] = cipher[i] ^ key[i % strlen(key)];
  fp2=fopen(argv[2],"wb");
  fwrite(plain,1,l,fp2);
  fclose(fp2);
  return 0;
}
Avatar billede blizim Nybegynder
06. maj 2005 - 16:03 #8
haha, tror lige det er gået op for mig hvor elendig jeg er til c++ :s kunne godt blive et problem
Avatar billede blizim Nybegynder
06. maj 2005 - 16:09 #9
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
  int i;
  char plain[] = "Dette er en lille test";
  char key[] = "TBFRGFARFM";
  char *cipher;
  int l = strlen(plain);
  cipher = (char *)malloc(l);
  for(i=0;i<l;i++) cipher[i] = plain[i] ^ key[i % strlen(key)];
  cipher[l] = '\0';
  printf("%s -> %s\n",plain,cipher);
  for(i=0;i<l;i++) plain[i] = cipher[i] ^ key[i % strlen(key)];
  plain[l] = '\0';
  printf("%s -> %s\n",cipher,plain);
}

malloc er? og bliver utrolig forvirret ved %s -> %s\n osv, forstår det bare ikke :S
Avatar billede arne_v Ekspert
06. maj 2005 - 16:12 #10
C:

cipher = (char *)malloc(l);

C++:

cipher = new char[l];
Avatar billede arne_v Ekspert
06. maj 2005 - 16:15 #11
C:

printf("%s -> %s\n",cipher,plain);

C++:

cout << cipher << " -> " << plain << endl;
Avatar billede blizim Nybegynder
06. maj 2005 - 16:18 #12
hehe takker, så gav det da i det mindste lidt mere menning :)
Avatar billede blizim Nybegynder
06. maj 2005 - 16:24 #13
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int main()
{
  int i;
  char plain[] = "Dette er en lille test";
  char key[] = "TBFRGFARFM";
  char *cipher;
  int l = strlen(plain);
  cipher = new char[l];
 
  for(i=0;i<l;i++) cipher[i] = plain[i] ^ key[i % strlen(key)];
  cipher[l] = '\0';
  cout << plain << " -> " << cipher << endl;
 
  for(i=0;i<l;i++) plain[i] = cipher[i] ^ key[i % strlen(key)];
  plain[l] = '\0';
  cout << cipher << " -> " << plain << endl;

  system("pause");
}

hvorfor siger den fejl ved cout :S
Avatar billede blizim Nybegynder
06. maj 2005 - 16:31 #14
hihi, doh! har fundet ud af det.. men min c++ bog hjælper mig ikke rigtig med at forstå key[i % strlen(key)]... strlen er længden af key .. men i % strlen(key), forstår ikke hvad det betyder ..
Avatar billede arne_v Ekspert
06. maj 2005 - 16:59 #15
% er modulus operatoren
Avatar billede blizim Nybegynder
06. maj 2005 - 16:59 #16
for ikke at virke hel dum ved jeg godt at i modulo strlen(key= må være noget med om i går op i strenglængden, men kan ikke se hvorfor det bruges i sammenhænget :S
Avatar billede arne_v Ekspert
06. maj 2005 - 17:00 #17
I praksis gentager den key om og om igen

Dette er en lille test
TBFRGFARFMTBFRGFARFMTB
Avatar billede arne_v Ekspert
06. maj 2005 - 17:01 #18
hvis keylængde er 10

så skal data index 0,10,20,... bruge key index 0
så skal data index 1,11,21,... bruge key index 1
...
så skal data index 9,19,29,... bruge key index 9
Avatar billede blizim Nybegynder
06. maj 2005 - 17:04 #19
ahh okay .. har et spørgsmål mere :D når jeg kryptere det, så bliver den krypteret version noget være lort :D sidst jeg legede med xor kryptering så blev det til tal :S hvorfor gør det ikke det lige nu?
Avatar billede arne_v Ekspert
06. maj 2005 - 17:06 #20
Output fra den der kryptering kan meget nemt blive binær og kab derfor ikke
skrives ud med printf/cout<< etc..

Den kan sagtens skrives til fil og læses ind derfra igen.
Avatar billede arne_v Ekspert
06. maj 2005 - 17:07 #21
Hvis du vil have den som tekst kan du konvertere de binære data til hex eller base64
Avatar billede blizim Nybegynder
06. maj 2005 - 17:09 #22
okay .. :) må se om jeg kan finde info om hvordan man gør det..

kom også til at tænke på hvorfor sætte det lig NULL, gør det en forskel?
Avatar billede arne_v Ekspert
06. maj 2005 - 17:10 #23
Sætte hvad lig NULL ??
Avatar billede blizim Nybegynder
06. maj 2005 - 17:11 #24
cipher[l] = '\0';

og

plain[l] = '\0';

betyder '\0' ikke null :)
Avatar billede arne_v Ekspert
06. maj 2005 - 17:11 #25
for(i=0;i<strlen(s);i++)
    {
        printf("%02x",(unsigned char)s[i]);
    }

kan udskrive i hex !
Avatar billede blizim Nybegynder
06. maj 2005 - 17:12 #26
Fatter dej af C, så kan ikke lige just omskrive det til C++
Avatar billede arne_v Ekspert
06. maj 2005 - 17:13 #27
'\0' er ikke NULL pointer men en NUL byte

den terminerer strengen

plain[l] = '\0';

gør at den afsluttes ved index l

cipher[l] = '\0';

er sådan lidt mere grumset da cipher jo som sagt kan indeholde binære data
Avatar billede arne_v Ekspert
06. maj 2005 - 17:14 #28
man kan godt bbruge printf/sprintf i C++

men jeg kan godt prøve at omskrive den til "rigtig C++"
Avatar billede blizim Nybegynder
06. maj 2005 - 17:15 #29
jep, ved godt man kan bruge begge, synes bare ikke der er optimalt at rode rundt i de to :)
Avatar billede arne_v Ekspert
06. maj 2005 - 17:48 #30
Eksempel:

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>

using namespace std;

int main()
{
  char *s = "\x33\x44\x55";
  printf("%s\n",s);
  cout << s << endl;
  for(int i=0; i<strlen(s); i++) printf("%02X",(unsigned char)s[i]);
  printf("\n");
  cout.width(2);
  cout.flags(ios::hex);
  for(int i=0; i<strlen(s); i++) cout << (int)(unsigned char)s[i];
  cout << endl;
  return 0;
}
Avatar billede arne_v Ekspert
06. maj 2005 - 17:48 #31
som C++ programmør bør du kende noget til C
Avatar billede blizim Nybegynder
08. maj 2005 - 12:49 #32
Hvis du vil have dine point, skal du lige ligge et svar :) mange tak for hjælpen
Avatar billede arne_v Ekspert
08. maj 2005 - 12:52 #33
kommer her
Avatar billede blizim Nybegynder
08. maj 2005 - 14:13 #34
'\0' er ikke NULL pointer men en NUL byte

den terminerer strengen

plain[l] = '\0';

gør at den afsluttes ved index l

cipher[l] = '\0';

er sådan lidt mere grumset da cipher jo som sagt kan indeholde binære data

>> forstår ikke hvorfor dette skal gøres :S
Avatar billede arne_v Ekspert
08. maj 2005 - 14:16 #35
plain[l] = '\0';

er nødvendig for at markere afslutningen på strengen

cipher[l] = '\0';

tja - den bør være der hvis man skal cout << cipher, men det bør man slet
ikke da cipher jo er binær
Avatar billede arne_v Ekspert
08. maj 2005 - 14:17 #36
C og C++ gemmer normalt tekst i achar arrays hvor man markerer
afslutningen med en nul byte

nyere C++ har så en decideret tekst data type STL string
Avatar billede blizim Nybegynder
08. maj 2005 - 14:23 #37
hmm okay, men hvad forskel gør det om det er der eller ej :S
Avatar billede arne_v Ekspert
08. maj 2005 - 14:56 #38
hvis

plain[l] = '\0';

mangler så kan du få udskrevet garbage efter de rigtige data.

hvis

cipher[l] = '\0';

mangler så får du nok udskrevet mere garbage end du gør med.  :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester