Generowanie losowego tekstu w C++ | ALGORYTM na random-string

Dzisiaj kolejna porcja kodu i programowania w C++. Pokażemy jak wygenerować losowy ciąg ze zdefiniowanych znaków i go przetasować (tak jak tablice elementów). Wielu osobom może to się przydać do losowania pseudolosowego stringa, który możemy użyć jako klucz do szyfrowania o w miarę unikalnym rozkładzie znaków. Funkcja genText() może dodatkowo posłużyć komuś do losowania sobie silnych haseł :-). Motywacją do napisania tej funkcji i publikacji źródła była chęć kontynuowania poprzedniego wpisu o szyfrowaniu xor i pisaniu cryptera. Z połączeniu obu funkcji mamy już generowanie automatyczne dosyć fajnego klucza szyfrującego o zdefiniowanej przez nas długości no i samo szyfrowanie XOR. W jednym z kolejnych wpisów połączymy to w całość.

Dodatkowo dodamy funkcje dopisywania tego zaszyfrowanego pliku naszym losowym kluczem do innego pliku. W ten sposób powstanie pewnego rodzaju binder/crypter/packer zmniejszający za każdym razem wykrywalność pliku (FUD) i łączący plik wykonywalny z np. zdjęciem w formacie jpeg.

Generowanie pseudoloswego stringa && tasowanie

Dzisiaj przedstawiamy kompletny kod źródłowy kompilowany i sprawdzany w Code::Blocksie i Netbeansie. Zezwalamy na użytkowanie go za darmo w dowolnych waszych projektach. Kod jest naszym autorskim algorytmem i dosyć bogato skomentowany, więc nawet początkującym adeptom programowania w C++ nie sprawi problemu zrozumienie go.

/*
 * File:   genText.cpp
 * Author: haker.edu.pl
 * License: MIT (X11)
 * Created on 10 pazdziernika 2015
 * genText(int, bool) - generate random string && shuffles array (buffor)
 */

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;

const char * genText(int max, bool potasuj = true) {
    /*
     *  Funkcja generuje losowy ciąg. 
     *   -argument max to długość wygenerowanego ciągu
     *   -argument potasuj aktywuje dodatkowe przemieszanie ciagu (domyslny argument)
    */

    //Cztery tablice z roznymi typami znakow. Mozna modyfikowac!
    char tab0[] = "abcdefghijklmnopqrstuvwxyz";
    char tab1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char tab2[] = "0123456789";
    char tab3[] = "!@#$%^&*(),.";
    //Tablica flag z uzytymi juz tablicami. Zapewnia rownomierny rozklad uzycia wszystkich tablic z znakami podobna ilosc razy)
    bool vistTab[] = {0, 0, 0, 0};
    //Zwracany ciag
    string buffor;

    srand(time(NULL));

    //Petla generowania znak po znaku
    for (int i = 0; i < max; i++) {
        //Sprawdz czy wszystkie 4 tablice juz uzyte byly, jesli tak to zezwol ponownie na wylosowanie wszystkich tablic
        if (vistTab[0] == true && vistTab[1] == true && vistTab[2] == true && vistTab[3] == true)
            vistTab[0] = vistTab[1] = vistTab[2] = vistTab[3] = false;


        //Sprawdz czy wylosowany typ tablicy nie byl juz wykorzystywany, jak byl to losuj inna
        int randTab;
        do {
            randTab = rand() % 4;
        } while (vistTab[randTab] == true);
        vistTab[randTab] = 1;

        int sizeTab = 0;
        int nr;

        //Zaleznie od wylosowanej powyzej tablicy ze znakami, losuje z niej znak i dopisuje go do buffora
        switch (randTab) {
            case 0:
                sizeTab = sizeof (tab0) / sizeof (tab1[0]) - 1;
                nr = rand() % sizeTab;
                buffor += tab0[nr];
                break;

            case 1:
                sizeTab = sizeof (tab1) / sizeof (tab1[0]) - 1;
                nr = rand() % sizeTab;
                buffor += tab1[nr];
                break;

            case 2:
                sizeTab = sizeof (tab2) / sizeof (tab2[0]) - 1;
                nr = rand() % sizeTab;
                buffor += tab2[nr];
                break;

            case 3:
                sizeTab = sizeof (tab3) / sizeof (tab3[0]) - 1;
                int nr = rand() % sizeTab;
                buffor += tab3[nr];
                break;
        }
    }

    //Dodatkowe przetasowanie (mieszanie pseudolosowe/shuffles array). Zapewnia jeszcze lepszy rozklad znakow (OPCJONALNE)!
    //Losuje dwa elementy z wygenerowane ciagu (buffor) i zamienia je miejscami. Zmienna vmax okresla ilosc takich przetasowan
    //cout << buffor << endl; //odkomentowujac mozesz sprawdzic jak wyglada bez przetasowania
    if (potasuj == true) {
        int vmax = max * 4;
        char randA;
        char randB;
        char tmp;
        for (int i = 0; i <= vmax; i++) {
            randA = rand() % max;
            randB = rand() % max;

            tmp = buffor[randA];
            buffor[randA] = buffor[randB];
            buffor[randB] = tmp;
        }
    }
    //------------------------------------------------

    return buffor.c_str();
}

int main() {
    cout << genText(64, true);
    return 0;
}
wygenerowane 64 bitowe stringi
Przykładowe wygenerowane pseudolosowe 64 ciągi (klucze).

Schemat blokowy losowania tekstu

Poniżaj dodatkowo dla chętnych umieszczam uproszczony schemat blokowy działania tego algorytmu. Sklecony w krótkiej przerwie na kolanie w samochodzie ;-). Implementacja została w pełni odzwierciedlona w C++. W poniższym schemacie blokowym brakuje tylko przetasowania tablicy (shuffles array), którą zdecydowałem się dodać później jako opcjonalna dodatkowa funkcja zwiększająca losowość ciągu.

schemat blokowy - losowanie stringa
Schemat blokowy – generowanie pseudolosowego ciągu znakowego o zrównoważonym rozkładzie typów znaków.

Inne wpisy które mogą Ciebie zainteresować:

Zapraszamy również na naszego fejsbuka HakerEduPL, aby być na bieżąco :-).

2 thoughts to “Generowanie losowego tekstu w C++ | ALGORYTM na random-string”

  1. Sporo artykułów już :), a żeby było więcej polecam coś napisać o metasploice, jak napisać exploita i shellcode. Tyle wiedzy ile przeciętny czytacz przyswoił może przejść na hight-level

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *