Antzinako makulu makulu zahar baten gainean

Oztoporik gabe hasiko naiz, behin errebelazio bat izan dudanean (beno, ez oso indartsua, egia esateko) eta irudi bat bezero batetik zerbitzari batera transferitzen duen programa bat inprimatzeko ideia sortu zen. Nahikoa sinplea ezta? Beno, esperientziadun programatzaile batentzat, hala izango da. Baldintzak sinpleak dira: ez erabili hirugarrenen liburutegiak. Printzipioz, apur bat konplikatuagoa da, baina konturatu eta adibideak bilatu behar direla ikusita, tira, halako lanbidea. Zeregin hori nire esku zegoela erabaki nuen. Gainera, komeni da nahikoa kode egotea, laguntza behar izanez gero foroan argitaratu ahal izateko. Lehenik eta behin, nire begiak FTPra erori ziren, bide batez, Windows garatzen ari den OSa. FTP-ren abantaila irudi bat ez ezik, edozein fitxategi transferi dezakezula da. Filezilla Server deskargatu ondoren, irakurtzeko / idazteko direktorio bat partekatu eta pasahitz batekin erabiltzaile bat sortu ondoren, Filezilla Bezeroa konektatzen saiatu nintzen, dena funtzionatu zuen. Kode adibide sinple bat sortu nuen C/C++-n:

#include <iostream>
void main()
{
	FILE* fs;
	fopen_s(&fs, "1.txt", "w");
	if (fs)
	{
    fwrite("userrnpasswordrnsend D:\share.txtrnbye", 1, sizeof("userrnpasswordrnsend D:\share.txtrnbye"), fs);
    fwrite("00", 1, sizeof("00"), fs);
    fclose(fs);
	}
	system("ftp -s:1.txt 127.0.0.1");
}

Nire memoriak balio badu, dena funtzionatu zuen localhost-en, eta sarearen bidez transmititzean, errore bat gertatu da bidalketarekin lerroan. Hemen komenigarria dena a) laburki b) ez duzu bezerorik instalatu behar, baina erabili Microsoft-en ftp-rako dagoeneko integratutako tresna. Nire ustez programen eta osagaien bidez aktibatu behar den arren. Metodo honen arazoa zein den jakin eta iruzkinetan idazten baduzu, bikaina izango da.

Foro mordo batean erantzunik aurkitu ez nuenez, kode hau utzi eta socket sareetarako interfazea erabiltzea erabaki nuen. Dagoeneko izan nuen beste programa batera karaktere sorta bat pasatzeko esperientzia. Bide batez, Tanenbaum-en irakur dezakezu, Sare informatikoak, garraio-geruzari buruzko kapituluan. Bezero eta zerbitzari baten adibide bat dago, baina ez "bezero asko - zerbitzari bat" konexiorako, baizik eta "bezero bat - zerbitzari bat". Transmisioa Internet bidez egiten denez, datuak nolabait enkriptatu behar dituzu. Horretarako, bloke zifratua erabiltzen da - Feistel sarea. Gainera zerbitzarian beharrezkoa da hainbat bezero (bezero bat baino gehiago) egitea. Horretarako, Threads erabiliko dugu, transmisiorako irudiak pantailaren pantaila-argazkia hartuko du bezeroarengandik, enkriptatu eta zerbitzarira bidaliko da, non deszifratu eta berehala pantailan bistaratuko den irekitzeko programa lehenetsiaren bidez * .tga irudiak.

Zerbitzariaren kodea:

#include <iostream>
#include <WinSock.h>
#pragma comment (lib,"WS2_32.lib")

#include <fstream>
#include <algorithm>
#include <string>
#include <iterator>
#include <vector>
void error(const char* msg)
{
    //perror(msg);
    std::cout<<'n'<<WSAGetLastError();
    WSACleanup();
    std::cin.ignore();
    exit(1);
}
void bzero(char*buf, int l)
{
    for (int i = 0; i < l; i++)
        buf[i] = '';
}
struct arg_s
{
    unsigned char* buffer2;
    bool exit;
};
char** buffer;
struct arg_sa
{
    struct arg_s* lalk;
    int current;
};
#define type struct arg_sa
int sockfd, * newsockfd;//ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ ΠΈ массив клиСнтских сокСтов
int buflen2 = 10292000;//ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ изобраТСния Π² Π±Π°ΠΉΡ‚Π°Ρ… для RGBA*Width*Height
struct sockaddr_in *cli_addr;
int* clilen;
int currentclient,cc;//сс-ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎ счСту(для записи ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π° ΠΈΠΌΠ΅Π½ΠΈ Ρ„Π°ΠΉΠ»Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° изобраТСния)

typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
#define N 8//Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±Π»ΠΎΠΊΠ°
#define F32 0xFFFFFFFF
uint32_t RK[N];//Ρ€Π°ΡƒΠ½Π΄ΠΎΠ²Ρ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ
#define size64 sizeof(uint64_t)
#define ROR(x,n,xsize)((x>>n)|(x<<(xsize-n)))
#define ROL(x,n,xsize)((x<<n)|(x>>(xsize-n)))
#define RKEY(r)((ROR(K,r*3,size64*8))&F32)
const uint64_t K = 0x96EA704CFB1CF671;//ΠΊΠ»ΡŽΡ‡ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ
struct hostent* server;
uint32_t F(uint32_t subblk, uint32_t key)
{
    return subblk + key;//функция ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ
}
void createRoundKeys()
{
    for (int i = 0; i < N; i++)
        RK[i] = (ROR(K, i * 8, size64 * 8)) & F32;
}
uint64_t decrypt(uint64_t c_block)//Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²ΠΊΠ° Π±Π»ΠΎΠΊΠΎΠ² ΡΠ΅Ρ‚ΡŒΡŽ фСйстСля
{
    //select subblocks
    uint32_t left = (c_block >> 32) & F32;
    uint32_t right = c_block & F32;
    uint32_t left_, right_;//subblock in the end of round
    for (int r = N - 1; r >= 0; r--)
    {
        uint32_t fk = F(left, RK[r]);
        left_ = left;
        right_ = right ^ fk;
        if (r > 0)//swap places to next round
        {
            left = right_;
            right = left_;
        }
        else //last round not swap
        {
            left = left_;
            right = right_;
        }
    }
    //collect subblock in block
    uint64_t block = left;
    block = (block << 32) | (right & F32);
    return block;
}
void session_(LPVOID args)//функция ΠΏΠΎΡ‚ΠΎΠΊΠ° ля ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
{
    int current = currentclient++;
    bzero((char*)&(cli_addr[current]), sizeof(&(cli_addr[current])));
    newsockfd[current] = accept(sockfd, (struct sockaddr*)&(cli_addr[current]), &(clilen[current]));
    if (newsockfd[current] < 0)
    {
        error("Error on acceptn");
    }
    char* s = new char[100];
    int n = recv(newsockfd[current], s, 100, 0);
    int buflen2 = atoi(s);//ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ число Π±Π°ΠΉΡ‚ΠΎΠ² изобраТСния
    FILE* f;
    std::string name = "Screen";
    cc++;
    _itoa_s(cc, s, 100, 10);
    name += s;
    name += ".tga";
    fopen_s(&f,name.c_str(), "wb");//создаСм Ρ„Π°ΠΉΠ» изобраТСния с увСличиваСщимся Π½Π° 1 ΠΈΠΌΠ΅Π½Π΅ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ
    if (f != NULL)
    {
        unsigned char tgaHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        unsigned char header[6];
        n = recv(newsockfd[current], buffer[current], sizeof(tgaHeader), 0);
        fwrite((unsigned char*)buffer[current], 1, sizeof(tgaHeader), f);
        bzero(buffer[current], buflen2);
        n = recv(newsockfd[current], buffer[current],sizeof(header), 0);
        fwrite((unsigned char*)buffer[current], 1, sizeof(header), f);//записали Ρ…ΠΈΠ΄Π΅Ρ€Ρ‹
        bzero(buffer[current], buflen2);
        n = recv(newsockfd[current], buffer[current], buflen2, 0);//ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ Π±Π°ΠΉΡ‚Ρ‹ самого изобраТСния
        //
        //Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²ΠΊΠ° Π±Π°ΠΉΡ‚ΠΎΠ²
        createRoundKeys();
        unsigned long long id;
        std::vector<uint64_t>* plaintext = new std::vector<uint64_t>();
        int i = 0;
        while (i<buflen2)
        {
            memcpy(&id, (buffer[current]) + i, N);
            plaintext->push_back(decrypt(id));
            i += 8;
        }
        std::cout << "i=" << i << std::endl;
        i = 0;
        char str_[N + 1];
        memset(str_, 0, N);
        str_[N] = '';
        for (std::vector<uint64_t>::iterator it = plaintext->begin(); it != plaintext->end(); ++it)
        {
            memcpy(str_, &*it, N);
            fwrite((unsigned char*)str_, sizeof(unsigned char), N/*strlen(str_)*/, f);
            i += 8;
        }
        std::cout << "i=" << i << std::endl;
        //ΠΊΠΎΠ½Π΅Ρ† Ρ€Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²ΠΊΠΈ Π±Π°ΠΉΡ‚ΠΎΠ²
        //fwrite((unsigned char*)buffer[current], sizeof(char), buflen2, f);
        fclose(f);
    }
    system(name.c_str());//ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ *.tga встроСнным Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ΠΎΠΌ
}
int main()
{
    cc = 0;
    WSADATA ws = { 0 };
    if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)
    {
        currentclient = 0;
        int maxclients = 2;//максимальноС число ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ²
        cli_addr = new struct sockaddr_in[maxclients];
        clilen = new int[maxclients];
        buffer = new char* [maxclients];
        for (int i = 0; i < maxclients; i++)
        {
            clilen[i] = sizeof(cli_addr[i]);
        }
        sockfd = socket(AF_INET, SOCK_STREAM, 0);//tcp сокСт
        if (sockfd < 0)
            error("ERROR opening socket");
        struct sockaddr_in serv_addr;
        bzero((char*)&serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        int port = 30000;//ΠΏΠΎΡ€Ρ‚
        serv_addr.sin_port = htons(port);
        if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
            error("ERROR on binding");
        if (listen(sockfd, 10) < 0)
            error("ERROR listen");
        HANDLE* thread;//массив ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ
        struct arg_sa* args;
        while (true)
        {
            newsockfd = new int[maxclients];
            thread = (HANDLE*)malloc(sizeof(HANDLE) * maxclients);
            args = new struct arg_sa[maxclients];
            for (int i = 0; i < maxclients; i++)
            {
                args[i].lalk = new struct arg_s();
                buffer[i] = new char[buflen2];
            }
            int i = -1;
            while (++i < maxclients)
            {
                Sleep(1);
                args[i].current = i;
                args[i].lalk->exit = false;
                thread[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)(session_), args, 0, 0);
            }
                for (int i = 0; i < maxclients; i++)
                    WaitForSingleObject(thread[i], INFINITE);//ΠΆΠ΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ всСх ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
            i = -1;
            while (++i < maxclients)
            {
                shutdown(newsockfd[i], 0);
                TerminateThread(thread[i], 0);
            }
            //delete[] newsockfd;
            //free(thread);
            currentclient = 0;
            for (int i = 0; i < maxclients; i++)
            {
                //delete args[i].lalk;
                //delete[] args[i].lalk->buffer;
            }
            //delete[] args;
        }
        shutdown(sockfd, 0);
        WSACleanup();
        return 0;
    }
    std::cin.ignore();
}

Laburbilduz, betiko begizta batean, bezero bakoitzarentzat hariak sortzen dira eta bezeroak konektatu arte onartu arte itxaron. Horren ostean, WaitForSingleObject guztiak gainditu arte itxarongo du. Bezero bakoitzak bere socket eta bidalketa buffer propioa ditu. Hau da, zerbitzarian M+1 socket daude, non M bezero kopurua den. Transferentzia guztiak amaitu ondoren, dena errepikatzen da.

Orain kontuan hartu bezeroa:

#include <iostream>
#include <WinSock.h>
#include <vector>
#pragma comment (lib,"WS2_32.lib")
void error(const char* msg)
{
    //perror(msg);
    std::cout << 'n' << WSAGetLastError();
    WSACleanup();
    std::cin.ignore();
    exit(1);
}
void bzero(char* buf, int l)
{
    for (int i = 0; i < l; i++)
        buf[i] = '';
}
typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
#define N 8
#define F32 0xFFFFFFFF
uint32_t RK[N];//Ρ€Π°ΡƒΠ½Π΄ΠΎΠ²Ρ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ
#define size64 sizeof(uint64_t)
#define ROR(x,n,xsize)((x>>n)|(x<<(xsize-n)))
#define ROL(x,n,xsize)((x<<n)|(x>>(xsize-n)))
#define RKEY(r)((ROR(K,r*3,size64*8))&F32)
const uint64_t K = 0x96EA704CFB1CF671;//ΠΊΠ»ΡŽΡ‡ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ
void createRoundKeys()
{
    for (int i = 0; i < N; i++)
        RK[i] = (ROR(K, i * 8, size64 * 8)) & F32;
}
uint32_t F(uint32_t subblk, uint32_t key)
{
    return subblk + key;//функция ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ
}
uint64_t encrypt(uint64_t block)//Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²ΠΊΠ° Π±Π»ΠΎΠΊΠΎΠ² ΡΠ΅Ρ‚ΡŒΡŽ ЀСйстСля
{
    //select subblocks
    uint32_t left = (block >> 32) & F32;
    uint32_t right = block & F32;
    uint32_t left_, right_;//subblock in the end of round
    for (int r = 0; r < N; r++)
    {
        uint32_t fk = F(left, RK[r]);
        left_ = left;
        right_ = right ^ fk;
        if (r < N - 1)//swap places to next round
        {
            left = right_;
            right = left_;
        }
        else//last round not swap
        {
            left = left_;
            right = right_;
        }
    }
    //collect subblock in block
    uint64_t c_block = left;
    c_block = (c_block << 32) | (right & F32);
    return c_block;
}
int main()
{
    keybd_event(VK_LWIN, 0, 0, 0);
    keybd_event('M', 0, 0, 0);
    keybd_event('M', 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);//эти строки ΡΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°ΡŽΡ‚ всС прилоТСния
    Sleep(1000);//Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡΠΊΡ€ΠΈΠ½ΡˆΠΎΡ‚ Ρ€Π°Π±ΠΎΡ‡Π΅Π³ΠΎ стола
    WSADATA ws = { 0 };
    if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)
    {
        int sockfd;
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        struct sockaddr_in serv_addr, cli_addr;
        bzero((char*)&serv_addr, sizeof(serv_addr));
        bzero((char*)&cli_addr, sizeof(cli_addr));
        serv_addr.sin_family = AF_INET;

        const char* add = "127.0.0.1";//адрСс сСрвСра
        serv_addr.sin_addr.s_addr = inet_addr(add);
        int port = 30000;//ΠΏΠΎΡ€Ρ‚
        serv_addr.sin_port = htons(port);
        int servlen = sizeof(serv_addr);
        int n = connect(sockfd, (struct sockaddr*)&serv_addr, servlen);
        
        //Π½ΠΈΠΆΠ΅ ΠΊΠΎΠ΄ Π΄Π΅Π»Π°Π΅Ρ‚ ΡΠΊΡ€ΠΈΠ½ΡˆΠΎΡ‚
        HDC ScreenDC = GetDC(0);
        HDC MemoryDC = CreateCompatibleDC(ScreenDC);
        int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
        int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
        ScreenWidth = ((ScreenWidth - 1) / 4 + 1) * 4;
        BITMAPINFO BMI;
        BMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        BMI.bmiHeader.biWidth = ScreenWidth;
        BMI.bmiHeader.biHeight = ScreenHeight;
        BMI.bmiHeader.biSizeImage = ScreenWidth * ScreenHeight * 3;
        BMI.bmiHeader.biCompression = BI_RGB;
        BMI.bmiHeader.biBitCount = 24;
        BMI.bmiHeader.biPlanes = 1;
        DWORD ScreenshotSize;
        ScreenshotSize = BMI.bmiHeader.biSizeImage;
        unsigned char* ImageBuffer;
        HBITMAP hBitmap = CreateDIBSection(ScreenDC, &BMI, DIB_RGB_COLORS, (void**)&ImageBuffer, 0, 0);
        SelectObject(MemoryDC, hBitmap);
        BitBlt(MemoryDC, 0, 0, ScreenWidth, ScreenHeight, ScreenDC, 0, 0, SRCCOPY);
        DeleteDC(MemoryDC);
        ReleaseDC(NULL, ScreenDC);
        FILE* sFile = 0;
        unsigned char tgaHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        unsigned char header[6];
        unsigned char tempColors = 0;
        fopen_s(&sFile, "S.tga", "wb");
        if (!sFile) {
            exit(1);
        }
        header[0] = ScreenWidth % 256;
        header[1] = ScreenWidth / 256;
        header[2] = ScreenHeight % 256;
        header[3] = ScreenHeight / 256;
        header[4] = BMI.bmiHeader.biBitCount;
        header[5] = 0;
        fwrite(tgaHeader, 1, sizeof(tgaHeader), sFile);
        fwrite(header, sizeof(header), 1, sFile);
        //ΠΊΠΎΠ½Π΅Ρ† записали ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² Ρ„Π°ΠΉΠ»
        
        //ΡˆΠΈΡ„Ρ€ΡƒΠ΅ΠΌ Π±Π»ΠΎΠΊΠ°ΠΌΠΈ ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ изобраТСния ΠΊΡ€ΠΎΠΌΠ΅ Ρ…ΠΈΠ΄Π΅Ρ€ΠΎΠ²
        createRoundKeys();
        std::vector<uint64_t>* msg = new std::vector<uint64_t>(),*crpt = new std::vector<uint64_t>();
        unsigned long long id;
        int i = 0;
        while (i < BMI.bmiHeader.biSizeImage)
        {
            memcpy(&id, (ImageBuffer + i), N);
            msg->push_back(id);
            i += 8;
        }
        std::cout << "i=" << i << std::endl; 
        uint64_t cipher;
        i = 0;
        char str_[N + 1];
        memset(str_, 0, N);
        str_[N] = '';
        for (std::vector<uint64_t>::iterator it = msg->begin(); it != msg->end(); ++it)
        {
            cipher = encrypt(*it);
            memcpy(str_, &cipher, N);
            fwrite((unsigned char*)str_, sizeof(unsigned char), N, sFile);
            i += 8;
        }
        std::cout << "i=" << i << std::endl;
        //
        //fwrite(ImageBuffer, BMI.bmiHeader.biSizeImage, 1, sFile);
        std::cout << BMI.bmiHeader.biSizeImage << std::endl;
        fclose(sFile);
        DeleteObject(hBitmap);
        FILE* f;
        fopen_s(&f, "S.tga", "rb");
        int count = 0;
        if (f != NULL)
        {
            while (getc(f) != EOF)
                count++;//считаСм Π±Π°ΠΉΡ‚Ρ‹ изобраТСния Π² счСтчик Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡ‚ΠΎΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ
            fclose(f);
        }
        count -= 18;
        std::cout << count<< std::endl;
        char* s = new char[100];
        _itoa_s(count, s, 100, 10);
        n = send(sockfd, s, 100, 0);//ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ счСтчик
        char* buffer = new char[count];
        fopen_s(&f, "S.tga", "rb");
        size_t bytes;
        if (f != NULL)
        {
            memcpy(buffer, tgaHeader, sizeof(tgaHeader));
            n = send(sockfd, buffer, sizeof(tgaHeader), 0);
            bzero(buffer, count);
            memcpy(buffer, header, sizeof(header));
            n = send(sockfd, buffer, sizeof(header), 0);
            bzero(buffer, count);//ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ Ρ…ΠΈΠ΄Π΅Ρ€Ρ‹
            for(int i=0;i<18;i++)
                fgetc(f);
            bzero(buffer, count);
            bytes = fread(buffer, sizeof(unsigned char), count, f);
            n = send(sockfd,buffer, count, 0);//ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π±Π°ΠΉΡ‚Ρ‹ изобраТСния
            fclose(f);
        }
        Sleep(1000);
        shutdown(sockfd, 0);
        WSACleanup();
        //system("del S.tga");
        delete[] buffer,s;
        return 0;
    }
    //std::cin.ignore();
}

Hona hemen bezeroaren lanaren emaitza, S.tga pantaila-argazkiaren fitxategia, zifratuta

Antzinako makulu makulu zahar baten gainean

Mahaigaina dela dirudi.

Eta hona hemen zerbitzarira transferitu eta Screen.tga-k deskodetutako emaitza

Antzinako makulu makulu zahar baten gainean

Ikus dezakezunez, ohiko Feistel sarea ez da enkriptatzeko egokia, baina CBC eta CFB metodoak erabil ditzakezu, ziurrenik hobeto enkriptatuta egongo da, egia esateko, ez dut egiaztatu.

Eskerrik asko zure arreta!

Iturria: www.habr.com

Gehitu iruzkin berria