Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.66/29: Рейтинг темы: голосов - 29, средняя оценка - 4.66
32 / 30 / 4
Регистрация: 01.02.2014
Сообщений: 878
1

Подкиньте функцию base64_decode\encode

04.01.2015, 14:24. Показов 5503. Ответов 34
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Помогите найти функцию base64_decode\encode, я уже перепробовал все что нашол в гугле и ниодна не шифрует правильно, мб у кого завалялась
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.01.2015, 14:24
Ответы с готовыми решениями:

Разбираемся с функциями и пишем Encode & Decode
Напишите подпрограммы Encode (зашифровать) и Decode (расшифровать), которые получают два параметра...

Функции encode и decode. Строки. Шифрование на основе алфавита
Напишите подпрограммы Encode (зашифровать) и Decode (расшифровать), которые получают два параметра...

Подкиньте идею
Здравствуйте. Пишу потихоньку свой фреймворк для разработки игр. В главном цикле связанной список...

Подкиньте задачку
Подкиньте задачку какую-нибудь(да хоть от балды насочиняйте с потолка). Не обязательно сложный...

34
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
04.01.2015, 17:36 21
Author24 — интернет-сервис помощи студентам
Возможно ты немного недопонимаешь. Программа-кодер base64 вообще не работает с кодировками. Она работает с байтами. А вот байты, которые попадают на вход, зависят от используемой кодировки.

Добавлено через 3 минуты
Вот та же программа, но на входе строка в кодировке cp1251
Код
/tmp $ echo -n "qazwsx12вася3@mail.ru" | iconv -f utf-8 -t cp1251 | ./b64 -e 
cWF6d3N4MTLi4PH/M0BtYWlsLnJ1
Добавлено через 4 минуты
А вот назад
Код
/tmp $ echo -n cWF6d3N4MTLi4PH | ./b64 -d | iconv -f cp1251 -t utf-8 
qazwsx12вас

/tmp $ echo -n cWF6d3N4MTLi4PH/M0BtYWlsLnJ1 | ./b64 -d | iconv -f cp1251 -t utf-8
qazwsx12вася3@mail.ru
Хотя тут видно, что одна проблема в windows-реализации всё-таки есть. Символ 'я' был воспринят как конец файла. Но это нетрудно исправить.

Добавлено через 4 минуты
Впрочем, и проблема с буквой я тоже не в этой программе
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
04.01.2015, 18:35 22
Вот онлайн-сервис, где можно выбрать кодирову: http://foxtools.ru/Base64
На скрине результат, который можно сравнить с результатом работы кода, который я выложил.
Миниатюры
Подкиньте функцию base64_decode\encode   Подкиньте функцию base64_decode\encode  
0
32 / 30 / 4
Регистрация: 01.02.2014
Сообщений: 878
05.01.2015, 00:27  [ТС] 23
я понял, в общем выходит что мне нужна функция котороя работает с юникодом, мб хто знает где взять такую?
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
05.01.2015, 01:54 24
Цитата Сообщение от mh-coder Посмотреть сообщение
я понял, в общем выходит что мне нужна функция котороя работает с юникодом, мб хто знает где взять такую?
Неа. Все, что нужно тебе уже дали. Нужно только привести в соответствие кодировку, которую подаешь на вход алгоритму с кодировкой, которая используется при проверке. Т.е. если файл (исходник твой) у тебя в cp1251, то и проверять в онлайн сервисе тоже нужно используя cp1251. Все алгоритмы, которые тебе тут давали работают корректно, в том числе с использованием юникода. Как уже говорили, алгоритму base64 по барабану что обрабатывать - он работает с байтами.
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
05.01.2015, 05:59 25
Вот работа того же кода со строками в Unicode и в UTF-8:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int main()
{
    setlocale(0, "");
    
    //string str;// = "Проверка";
    
    // "Проверка" в UTF-8
    unsigned char arr[] = {0xD0, 0x9F, 0xD1, 0x80, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x80, 0xD0, 0xBA, 0xD0, 0xB0};
    
    // "Проверка" в Unicode
    //unsigned char arr[] = {0x1F, 0x04, 0x40, 0x04, 0x3E, 0x04, 0x32, 0x04, 0x35, 0x04, 0x40, 0x04, 0x3A, 0x04, 0x30, 0x04};
    
    string str(arr, arr + sizeof(arr));
    
    string encode = b64_encode(str);
    string decode = b64_decode(encode);
    
    cout << "\"Проверка\" в UTF-8" << endl;
    //cout << "\"Проверка\" в Unicode" << endl;
    
    cout << encode << endl;
    
    //cout << decode << endl;
    if (std::equal(str.begin(), str.end(), decode.begin()))
        cout << "Yes!" << endl;
    else 
        cout << "No!" << endl;
    
    system("pause");
}
Миниатюры
Подкиньте функцию base64_decode\encode   Подкиньте функцию base64_decode\encode   Подкиньте функцию base64_decode\encode  

Подкиньте функцию base64_decode\encode  
0
32 / 30 / 4
Регистрация: 01.02.2014
Сообщений: 878
05.01.2015, 15:16  [ТС] 26
lss, чёт вы меня совсем запутали, а зарве unicode и utf-8 это не одно и тоже? и почему оно влазит в чар? зарве юникод не больше одного байта?

откуда вы взяли эти значения? {0xD0, 0x9F, 0xD1, 0x80, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x80, 0xD0, 0xBA, 0xD0, 0xB0}

если как вы говорите base64 работает с байтами, почему при обработки юникода (wchat_t) я серовно не получаю результат как в онлаин сервисе?

Добавлено через 6 минут
давайте чтобы не парить друг другу мозги сделаем проще,

что нужно изменить в функции b64_encode что бы в результате получить cWF6d3N4MTLQstCw0YHRjzNAbWFpbC5ydQ==
вот код

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const string b64_chars = 
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";
 
inline bool is_b64(unsigned char c) 
{
  return (isalnum(c) || (c == '+') || (c == '/'));
}
 
 
wstring b64_encode(const wstring bytes_to_encode) 
{
  unsigned int in_len = bytes_to_encode.size(); 
  wstring ret;
  int i = 0;
  int j = 0;
  int n = 0;
  wchar_t char_array_3[3];
  wchar_t char_array_4[4];
 
  while (in_len--) 
  {
    char_array_3[i++] = bytes_to_encode[n++];
    if (i == 3) 
    {
      char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] =   char_array_3[2] & 0x3f;
 
      for(i = 0; (i < 4) ; i++)
        ret += b64_chars[char_array_4[i]];
      i = 0;
    }
  }
 
  if (i)
  {
    for(j = i; j < 3; j++)
      char_array_3[j] = '\0';
 
    char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] =   char_array_3[2] & 0x3f;
 
    for (j = 0; (j < i + 1); j++)
      ret += b64_chars[char_array_4[j]];
 
    while((i++ < 3))
      ret += '=';
  }
 
  return ret;
}
 
//................................................................. 
 
string b64_decode(const string &encoded_string) 
{
  unsigned int in_len = encoded_string.size();
  int i = 0;
  int j = 0;
  int in_ = 0;
  unsigned char char_array_4[4];
  unsigned char char_array_3[3];
  string ret;
 
  while (in_len-- && ( encoded_string[in_] != '=') && is_b64(encoded_string[in_])) 
  {
    char_array_4[i++] = encoded_string[in_]; 
    in_++;
    if (i ==4) 
    {
      for (i = 0; i <4; i++)
        char_array_4[i] = b64_chars.find(char_array_4[i]);
 
      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
 
      for (i = 0; (i < 3); i++)
        ret += char_array_3[i];
      i = 0;
    }
  }
 
  if (i) 
  {
    for (j = i; j <4; j++)
      char_array_4[j] = 0;
 
    for (j = 0; j <4; j++)
      char_array_4[j] = b64_chars.find(char_array_4[j]);
 
    char_array_3[0] = ( char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
 
    for (j = 0; (j < i - 1); j++) 
        ret += char_array_3[j];
  }
 
  return ret;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    
    setlocale(LC_ALL, "RUS");
 
    
    
    wchar_t * str = (wchar_t*)malloc(100);
    ZeroMemory(str,100);
    str = L"qazwsx12вася3@mail.ru";
    wstring res = b64_encode( str );
    free(str);
return 0;
 
}
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
05.01.2015, 17:09 27
Цитата Сообщение от mh-coder Посмотреть сообщение
что нужно изменить в функции b64_encode что бы в результате получить cWF6d3N4MTLQstCw0YHRjzNAbWFpbC5ydQ==
Ну нужно ничего менять. Возьми код из оригинального поста. Или любой другой код, который мы тут приводили.
Сохрани исходник в UTF-8.
Скомпилируй.
И получишь свою cWF6d3N4MTLQstCw0YHRjzNAbWFpbC5ydQ==
Вот пример. Компилятор на codepad.org как раз считает, что исходник в UTF-8.

Добавлено через 1 минуту
Цитата Сообщение от mh-coder Посмотреть сообщение
зарве unicode и utf-8 это не одно и тоже?
Unicode - это так в винде называют utf-16.
utf-8 использует char, потому что размер символа у нее плавающий, от 1 до 6 байт.
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
05.01.2015, 17:24 28
Или используй функции winapi для преобразования кодировок. Только правильно используй.
Вот так должно работать в VS. Но в VS не проверял.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <iostream>
#include <string>
#include <cstdlib>
#include <tchar.h>
#include <stringapiset.h>
 
using namespace std;
 
const string b64_chars = 
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";
 
inline bool is_b64(unsigned char c) 
{
  return (isalnum(c) || (c == '+') || (c == '/'));
}
 
 
string b64_encode(const string bytes_to_encode) 
{
  unsigned int in_len = bytes_to_encode.size(); 
  string ret;
  int i = 0;
  int j = 0;
  int n = 0;
  wchar_t char_array_3[3];
  wchar_t char_array_4[4];
 
  while (in_len--) 
  {
    char_array_3[i++] = bytes_to_encode[n++];
    if (i == 3) 
    {
      char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] =   char_array_3[2] & 0x3f;
 
      for(i = 0; (i < 4) ; i++)
        ret += b64_chars[char_array_4[i]];
      i = 0;
    }
  }
 
  if (i)
  {
    for(j = i; j < 3; j++)
      char_array_3[j] = '\0';
 
    char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] =   char_array_3[2] & 0x3f;
 
    for (j = 0; (j < i + 1); j++)
      ret += b64_chars[char_array_4[j]];
 
    while((i++ < 3))
      ret += '=';
  }
 
  return ret;
}
 
//................................................................. 
 
string b64_decode(const string &encoded_string) 
{
  unsigned int in_len = encoded_string.size();
  int i = 0;
  int j = 0;
  int in_ = 0;
  unsigned char char_array_4[4];
  unsigned char char_array_3[3];
  string ret;
 
  while (in_len-- && ( encoded_string[in_] != '=') && is_b64(encoded_string[in_])) 
  {
    char_array_4[i++] = encoded_string[in_]; 
    in_++;
    if (i ==4) 
    {
      for (i = 0; i <4; i++)
        char_array_4[i] = b64_chars.find(char_array_4[i]);
 
      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
 
      for (i = 0; (i < 3); i++)
        ret += char_array_3[i];
      i = 0;
    }
  }
 
  if (i) 
  {
    for (j = i; j <4; j++)
      char_array_4[j] = 0;
 
    for (j = 0; j <4; j++)
      char_array_4[j] = b64_chars.find(char_array_4[j]);
 
    char_array_3[0] = ( char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
 
    for (j = 0; (j < i - 1); j++) 
        ret += char_array_3[j];
  }
 
  return ret;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    
    setlocale(LC_ALL, "RUS");
 
    
    
    wchar_t const *wstr = L"qazwsx12вася3@mail.ru";
    char *str = (char*)malloc(100);
    ::WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, 100, NULL, NULL);
        
    string res = b64_encode( str );
    cout << res << endl;
    free(str);
return 0;
 
}
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
05.01.2015, 17:44 29
Цитата Сообщение от grizlik78 Посмотреть сообщение
Но в VS не проверял.
Я проверил. Вместо <stringapiset.h> лучше включить просто <windows.h>.
1
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
05.01.2015, 17:47 30
Не знаю, может и лучше. Я бы лучше iconv.h подключил
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
05.01.2015, 17:52 31
Да, и кодировка файла на этот раз должна быть cp1251 (для русской windows) Для преобразования в UTF-16 VS использует текущую системную локаль.

Добавлено через 35 секунд
Цитата Сообщение от grizlik78 Посмотреть сообщение
Не знаю, может и лучше. Я бы лучше iconv.h подключил
В VS2013, например, с <stringapiset.h> даже не компилируется
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
05.01.2015, 19:45 32
Цитата Сообщение от mh-coder Посмотреть сообщение
а зарве unicode и utf-8 это не одно и тоже?
С точки зрения последовательности байтов (а base64 работает с байтами) - нет (было бы одно и тоже, то здесь: http://foxtools.ru/Base64 не было бы разных пунктов).
Цитата Сообщение от mh-coder Посмотреть сообщение
и почему оно влазит в чар? зарве юникод не больше одного байта?
Где оно влазит? В слове "Проверка" 8 символов, а в массивах по 16 байтов (char).
Цитата Сообщение от mh-coder Посмотреть сообщение
откуда вы взяли эти значения? {0xD0, 0x9F, 0xD1, 0x80, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x80, 0xD0, 0xBA, 0xD0, 0xB0}
Перевёл слово "Проверка" в UTF-8 и посмотрел, как это выглядит в памяти (какая последовательность байтов).
Цитата Сообщение от mh-coder Посмотреть сообщение
если как вы говорите base64 работает с байтами, почему при обработки юникода (wchat_t) я серовно не получаю результат как в онлаин сервисе?
Потому, что wchar_t это не один байт, а base64 работает с байтами.
0
32 / 30 / 4
Регистрация: 01.02.2014
Сообщений: 878
06.01.2015, 01:38  [ТС] 33
grizlik78, в вашем примере работает как надо, всем спасибо, ток вот немного запутался, а что тогда такое кодировка по сути? вот допустим

C++ (Qt)
1
2
3
4
5
6
7
wchar_t const *wstr = L"a";
    char *str = (char*)malloc(1);
    ::WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, 1, NULL, NULL);
    
 
    int a = char('a'); // 97
    int b = char(str[0]); //97
что в обычном чаре, что в utf-8 буква ,,а,, = 97, почему тогде если через b64_encode преобразовать обычною чаровскою строку выходит один результат а если прогнать её через WideCharToMultiByte то другой?

тоесть

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
wchar_t const *wstr = L"qazwsx12вася3@mail.ru";
    char *str = (char*)malloc(100);
    char *str2 = (char*)malloc(100);
    ::WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, 100, NULL, NULL);
    str2 = "qazwsx12вася3@mail.ru";
 
    string res = b64_encode( str );   
    string res2 = b64_encode( str2 ); 
    
    free(str);
    free(str2);
b64_encode в первом и втором случае вернут разный результат, хотя значения букв одинаковые, в чём разнаца между str и str2 ?
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
06.01.2015, 02:12 34
Цитата Сообщение от mh-coder Посмотреть сообщение
что в обычном чаре, что в utf-8 буква ,,а,, = 97
ASCII-часть одинаковая везде. 97 - это латинская `а`. Первые 127 кодов ASCII таблицы совпадают почти во всех кодировках. Разница начинается, когда в игру вступают локальные символы. Замени латинскую 'а' на русскую и увидишь разницу.

Цитата Сообщение от mh-coder Посмотреть сообщение
b64_encode в первом и втором случае вернут разный результат, хотя значения букв одинаковые, в чём разнаца между str и str2 ?
Буквы одинаковые, а коды у них разные. Алгоритм работает с целыми числами, байтами. Если байты разные, то и результат разный. Строка в utf-8 и в локальной кодировке - это разные байты, за исключением первых 127 байт ASCII таблицы. Поэтому строка в разных кодировках даст одинаковый результат при преобразовании base64 только в том случае, если она ограничивается символами с кодами из этих 127 байт, в остальных случаях результат будет разный.
1
337 / 185 / 80
Регистрация: 22.08.2013
Сообщений: 724
08.01.2015, 10:43 35
DrOffset, возник вопрос по коду из 19 поста. Зачем, перед сдвигом, сбрасываются биты, в направлении сдвига, вот в этих выражениях:
char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2; // сброс двух справа, и сдвиг на два вправо
... + ((char_array_3[1] & 0xf0) >> 4); // сброс четырёх справа, и сдвиг на четыре вправо
... + ((char_array_3[2] & 0xc0) >> 6); // сброс шести справа, и сдвиг на шесть вправо
Разве тут недостаточно просто сдвига?
0
08.01.2015, 10:43
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.01.2015, 10:43
Помогаю со студенческими работами здесь

Подкиньте идею:)
В общем хочу написать прогу для того чтобы обмануть систему проверки на плагиат контрольных в...

Подкиньте практику по С/С++
Подкиньте пару сайт или книг с практикой по С++. Этот форум не подходит, тут сильно сложные...

Подкиньте рандомно задачки
На темы: 1. Переменные. 2. Массивы. 3. Типы данных. 4. Циклы Что нить из этого.

Подкиньте код нарисованных фигур в с++
Подкиньте код для рисования фигур. Хочу попробовать что-то нарисовать


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru