Witam. Potrzebuję zamienić łańcuch znaków na liczbę typu int i na odwrót. Przykładowo napis "Kot" daje nam 4 i na odwrót deszyfrowanie z 4 otrzymujemy "Kot". Czy istnieją w C++ jakieś gotowe funkcje do tego? Czy może nie jest możliwe zrealizowanie czegoś takiego w C++? Znalazłem hash z functional, ale hashowanie działa szybko w jedną stronę. Przy odkodowaniu musiałbym porównywać a to za dużo czasu zajmuje.
0
0
Przykładowo napis "Kot" daje nam 4 i na odwrót deszyfrowanie z 4 otrzymujemy "Kot".
I tak każdemu słowu (i każdej formie słowa) chcesz przypisać inną liczbę?
1
Łap.
#include <iostream>
#include <string>
#include <exception>
using namespace std;
int encrypt(string str) {
if(str == "Kot") return 4;
throw exception{};
}
string decrypt(int num) {
if(num == 4) return "Kot";
throw exception{};
}
int main() {
string str = "Kot";
int encrypted = encrypt(str);
string decrypted = decrypt(encrypted);
cout << decrypted;
return 0;
}
1
To czego szukasz to mapa dwukierunkowa "bidirectional map".
http://www.boost.org/doc/libs/1_57_0/libs/bimap/doc/html/boost_bimap/one_minute_tutorial.html
1
W pewnej grze, autorzy wymyślili na to pewien sposób:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctype.h>
namespace prism
{
typedef unsigned long long int token_t;
struct _ulldiv_t
{
unsigned long long int quot;
unsigned long long int rem;
_ulldiv_t() : quot(0ull), rem(0ull) { }
};
_ulldiv_t _div(unsigned long long int num, unsigned long long int divider)
{
_ulldiv_t result;
result.rem = num%divider;
result.quot = (unsigned long long int)num / divider;
return result;
}
unsigned long long int powull(unsigned long long int base, long num)
{
unsigned long long int result = 1;
for (long i = 0; num > i; ++i)
result = result * base;
return result;
}
const int g_iNumLetters = 38;
const char g_pszLetters[g_iNumLetters] = "\00123456789abcdefghijklmnopqrstuvwxyz_";
void token_to_string(char* dest, const prism::token_t& token)
{
prism::token_t tokenCopy = token;
_ulldiv_t result;
int i = 0;
for (;tokenCopy != 0; ++i)
{
result = _div(tokenCopy, 38ull);
tokenCopy = result.quot;
dest[i] = g_pszLetters[result.rem];
}
dest[i] = '\0';
}
int get_id_char(char cLetter)
{
for (int i = 0; i < g_iNumLetters; ++i)
if (cLetter == g_pszLetters[i])
return i;
return 0;
}
token_t string_to_token(const char* str)
{
token_t result = 0;
unsigned len = strlen(str);
for (unsigned i = 0; i < len; i++)
result += powull(38, i) * (unsigned long long)get_id_char(tolower(str[i]));
return result;
}
}
int main(int, char**)
{
const char * szStr = "test_szyfr";
prism::token_t Result = prism::string_to_token(szStr);
printf("result = %llu\n", Result);
char Buffer[16] = { 0 };
prism::token_to_string(Buffer, Result);
printf("result = %s\n", Buffer);
return 0;
}
Aczkolwiek sposób taki sprawia, że w jednym tokenie możesz maksymalnie trzymać ze 12 znaków. A jakbyś jeszcze liter dołożył do tablicy to jeszcze mniej. Tym samym w typie 32 bitowym nie opłaca się tego trzymać, od razu trzeba 64 bitowy tworzyć. Tak czy inaczej.. ciekawa opcja do zapisywania w plikach, gdzie w ten sposób nie trzeba się martwić o długość stringów itd.