Форум программистов, компьютерный форум, киберфорум
C++/CLI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
3 / 3 / 2
Регистрация: 18.12.2014
Сообщений: 64

Конвертация массива байт в 62-ричную строку

27.08.2015, 18:29. Показов 1248. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужны алгоритмы перевода байт в 62-ричную строку и обратно. 10-цифры и их 62-ричное представление:
0...9 - 0...9
10...35 - a...z
36...62 - A...Z
У меня есть алгоритм перевода из любой сс в любую от 2 до 62, но он основан на арифметических операциях, поэтому работает нереально медленно. Нужны битовые штучки, типа этого:
(переводилка из байт в 64-строку, которую юзает Convert::ToBase64String, неважно, откуда я это взял)
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
private unsafe static int ConvertToBase64Array(char* outChars, byte* inData, int offset, int length)
{
    int num = length % 3;
    int num2 = offset + (length - num);
    int num3 = 0;
    int num4 = 0;
    fixed (char* ptr = Convert.base64Table)
    {
        int i;
        for (i = offset; i < num2; i += 3)
        {
            outChars[num3] = ptr[(inData[i] & 252) >> 2];
            outChars[num3 + 1] = ptr[(int)(inData[i] & 3) << 4 | (inData[i + 1] & 240) >> 4];
            outChars[num3 + 2] = ptr[(int)(inData[i + 1] & 15) << 2 | (inData[i + 2] & 192) >> 6];
            outChars[num3 + 3] = ptr[inData[i + 2] & 63];
            num3 += 4;
        }
        i = num2;
        switch (num)
        {
        case 1:
            outChars[num3] = ptr[(inData[i] & 252) >> 2];
            outChars[num3 + 1] = ptr[(inData[i] & 3) << 4];
            outChars[num3 + 2] = ptr[64];
            outChars[num3 + 3] = ptr[64];
            num3 += 4;
            break;
        case 2:
            outChars[num3] = ptr[(inData[i] & 252) >> 2];
            outChars[num3 + 1] = ptr[(int)(inData[i] & 3) << 4 | (inData[i + 1] & 240) >> 4];
            outChars[num3 + 2] = ptr[(inData[i + 1] & 15) << 2];
            outChars[num3 + 3] = ptr[64];
            num3 += 4;
            break;
        }
    }
    return num3;
}
Вот, как она обратно переводит:
(это взял оттуда, откуда и предыдущее)
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
private unsafe static int FromBase64_Decode(char* startInputPtr, int inputLength, byte* startDestPtr, int destLength)
{
    char* ptr = startInputPtr;
    byte* ptr2 = startDestPtr;
    char* ptr3 = ptr + inputLength;
    byte* ptr4 = ptr2 + destLength;
    uint num = 255u;
    while (ptr < ptr3)
    {
        uint num2 = (uint)(*ptr);
        ptr++;
        if (num2 - 65u <= 25u)
        {
            num2 -= 65u;
        }
        else if (num2 - 97u <= 25u)
        {
            num2 -= 71u;
        }
        else
        {
            if (num2 - 48u > 9u)
            {
                uint num3 = num2;
                if (num3 <= 32u)
                {
                    switch (num3)
                    {
                    case 9u:
                    case 10u:
                    case 13u:
                        continue;
                    case 11u:
                    case 12u:
                        break;
                    default:
                        if (num3 == 32u)
                        {
                            continue;
                        }
                        break;
                    }
                }
                else
                {
                    if (num3 == 43u)
                    {
                        num2 = 62u;
                        goto IL_BF;
                    }
                    if (num3 == 47u)
                    {
                        num2 = 63u;
                        goto IL_BF;
                    }
                    if (num3 == 61u)
                    {
                        if (ptr == ptr3)
                        {
                            num <<= 6;
                            if ((num & 2147483648u) == 0u)
                            {
                                throw new FormatException(Environment.GetResourceString("Format_BadBase64CharArrayLength"));
                            }
                            if ((int)((long)(ptr4 - ptr2)) < 2)
                            {
                                return -1;
                            }
                            *(ptr2++) = (byte)(num >> 16);
                            *(ptr2++) = (byte)(num >> 8);
                            num = 255u;
                            break;
                        }
                        else
                        {
                            while (ptr < ptr3 - 1)
                            {
                                int num4 = (int)(*ptr);
                                if (num4 != 32 && num4 != 10 && num4 != 13 && num4 != 9)
                                {
                                    break;
                                }
                                ptr++;
                            }
                            if (ptr != ptr3 - 1 || *ptr != '=')
                            {
                                throw new FormatException(Environment.GetResourceString("Format_BadBase64Char"));
                            }
                            num <<= 12;
                            if ((num & 2147483648u) == 0u)
                            {
                                throw new FormatException(Environment.GetResourceString("Format_BadBase64CharArrayLength"));
                            }
                            if ((int)((long)(ptr4 - ptr2)) < 1)
                            {
                                return -1;
                            }
                            *(ptr2++) = (byte)(num >> 16);
                            num = 255u;
                            break;
                        }
                    }
                }
                throw new FormatException(Environment.GetResourceString("Format_BadBase64Char"));
            }
            num2 -= 4294967292u;
        }
        IL_BF:
        num = (num << 6 | num2);
        if ((num & 2147483648u) != 0u)
        {
            if ((int)((long)(ptr4 - ptr2)) < 3)
            {
                return -1;
            }
            *ptr2 = (byte)(num >> 16);
            ptr2[1] = (byte)(num >> 8);
            ptr2[2] = (byte)num;
            ptr2 += 3;
            num = 255u;
        }
    }
    if (num != 255u)
    {
        throw new FormatException(Environment.GetResourceString("Format_BadBase64CharArrayLength"));
    }
    return (int)((long)(ptr2 - startDestPtr));
}
Эти коды на решетке, хотя чисто решеточных всего неск. операций. Нужны коды на с++/cli
Кто-нибудь в этом разбирается?

Добавлено через 4 минуты
про это и это я знаю, но в 64-системе присутствует нечто, кроме букв и цифр. Я хочу только буквы и цифры

Добавлено через 13 часов 27 минут
тут есть реализация этого на питоне, например:
Python
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
ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
def base62_encode(num, alphabet=ALPHABET):
    if (num == 0):
        return alphabet[0]
    arr = []
    base = len(alphabet)
    while num:
        rem = num % base
        num = num // base
        arr.append(alphabet[rem])
    arr.reverse()
    return ''.join(arr)
 
def base62_decode(string, alphabet=ALPHABET):
    base = len(alphabet)
    strlen = len(string)
    num = 0
 
    idx = 0
    for char in string:
        power = (strlen - (idx + 1))
        num += alphabet.index(char) * (base ** power)
        idx += 1
 
    return num
но все предложенные там варианты кодируют целые числа и используют арифметические операции. как из массива байт сделать целое число?
еще нашел на пхп:
PHP
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
function base62_encode ($data) {
    $outstring = '';
    $len = strlen($data);
    for ($i = 0; $i < $len; $i += 8) {
        $chunk = substr($data, $i, 8);
        $outlen = ceil((strlen($chunk) * 8) / 6);
        $x = bin2hex($chunk);
        $number = ltrim($x, '0');
        if ($number === '') $number = '0';
        $w = gmp_strval(gmp_init($number, 16), 62);
        $pad = str_pad($w, $outlen, '0', STR_PAD_LEFT);
        $outstring .= $pad;
    }
    return $outstring;
}
 
function base62_decode ($data) {
    $outstring = '';
    $len = strlen($data);
    for ($i = 0; $i < $len; $i += 11) {
        $chunk = substr($data, $i, 11);
        $outlen = floor((strlen($chunk) * 6) / 8);
        $number = ltrim($chunk, '0');
        if ($number === '') $number = '0';
        $y = gmp_strval(gmp_init($number, 62), 16);
        $pad = str_pad($y, $outlen * 2, '0', STR_PAD_LEFT);
        $outstring .= pack('H*', $pad);
    }
    return $outstring;
}
тут принимается строка и возвращается строка. Нужно что-то типа этого

Добавлено через 1 час 45 минут
можно исходный массив байт разделить на 8-байтовые блоки (если не делится, добить нулями), чтобы получить целые числа, и зашифровать их алгоритмом из питонного кода, на выходе соединить все зашифрованные блоки. Как расшифровать, я еще не придумал

Добавлено через 2 часа 37 минут
я сделал, но оно неправильно работает:
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
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
{
    array<Byte>^ data1 = Encoding::Default->GetBytes(textBox1->Text);
 
    array<Byte>^ data2;
    if((data1->Length % 4) == 0)
    {
        data2 = gcnew array<Byte>(data1->Length);
    }
    else
    {
        data2 = gcnew array<Byte>(data1->Length + (4 - (data1->Length % 4)));
    }
 
    int d = data2->Length - data1->Length;
    for(int i=0; i<data1->Length; i++) data2[i+d] = data1[i];
 
    String^ str = "";
    for(int i=0; i<data2->Length; i=i+4)
    {
        int num = BitConverter::ToInt32(data2, i);
 
        String^ ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String^ temp = "";
        while(num > 0)
        {
            int rem = num % 62;
            num /= 62;
            temp += ALPHABET[rem];
        }
        str+=temp;
    }
 
    textBox2->Text = str;
}
два текстбокса, одна кнопка. Для "11111111111111111111" дает "laUQTlaUQTlaUQTlaUQTlaUQT". Так не должно быть

Добавлено через 22 секунды
Никто не знает?

Добавлено через 1 час 18 минут
если никто не знает, как это сделать, оставлю системные Convert.ToBase64String и Convert.FromBase64String
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.08.2015, 18:29
Ответы с готовыми решениями:

Конвертация массива бит в массив байт
Есть ли в Java стандартные функции для конвертации массива бит в массив байт? При этом, что бы можно было менять размерность байтов: 1 байт...

Конвертация (приведение) типов от массива байт к строке и int
Добрый день. Искренне надеюсь на исправность ваших телепаторов, ибо судя по результатам поиска уж шибко некорректно я всё формулирую: На...

Перевод массива байт в строку и обратно
Здравсвуйте, в результате шифрования есть некоторая последовательность байт. Как преобразовать эту последовательность в строку...

2
Администратор
Эксперт .NET
 Аватар для tezaurismosis
9673 / 4825 / 763
Регистрация: 17.04.2012
Сообщений: 9,664
Записей в блоге: 14
28.08.2015, 07:47
Иван_Богданов, я уже упоминал в другой теме, что строки должны быть помечены префиксом L (строки 18, 23 и 24)
0
3 / 3 / 2
Регистрация: 18.12.2014
Сообщений: 64
28.08.2015, 14:54  [ТС]
Цитата Сообщение от tezaurismosis Посмотреть сообщение
строки должны быть помечены префиксом
если так сделать, результат не изменится, даже если так - String^ str = static_cast<String^>(L"") и т.д. - тоже

Добавлено через 1 час 2 минуты
но мне до сих пор интересно: у меня есть алгоритм перевода чисел из любой сс в любую (2-62), я взял его отсюда, переделал под NET-штучки, исправил фатальный баг (не помню, где именно) и расширил его возможности: предложенный вариант переводит только до 36-системы, мой до 62-ричной.
В cpp-файле:
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
//MyConverterCoreModule.cpp
#include "stdafx.h"
#include "MyConverterCoreModule.h"
#include <algorithm>
#include <string>
#include <vector>
 
using namespace MyConverterCoreModule;
using namespace Runtime::InteropServices;
using namespace System;
 
void MyConverter::myconvertWhatFromTo(String^ str0, int original, int final)
{
    invalidDigit = false;
    string str = sysToStd(str0);
    MyConverter::original = original;
    a = Array::CreateInstance(Int32::typeid, str.length());
    for (int i=0; i<(int)str.length(); i++) a->SetValue(charToInt(str[i]), i);
 
    vector<int> b;
    do
    {
        b.push_back(nextNumber(final));
    }
    while(!zero() && stopme == false);
    string sTemp = "";      
    for (int i=b.size()-1; i>=0; i--)
    {
        sTemp += intToChar(b[i]);
    }
    result = gcnew System::String(sTemp.c_str());
}
 
int MyConverter::charToInt(char c)
{
    if(c >= '0' && c <= '9' && (c - '0') < original)
    {
        return (c - '0');
    }
    else
    {
        if(c >= 'a' && c <= 'z' && (c - 'a' + 10) < original)
        {
            return (c - 'a' + 10);
        }
        else
        {
            if(c >= 'A' && c <= 'Z' && (c - 'A' + 36) < original)
            {
                return (c - 'A' + 36);
            }
            else
            {
                invalidDigit = true;
                return -1;
            }
        }
    }
}
 
char MyConverter::intToChar(int c)
{
    if(c >= 0 && c <= 9)   return c + '0';
    if(c >= 10 && c <= 35) return c + 'a' - 10;
    if(c >= 36 && c <= 62) return c + 'A' - 36;
}
 
int MyConverter::nextNumber(int final)
{
    int temp = 0;
    for(int i = 0; i<a->GetLength(0); i++)
    {
        temp = temp*original + Convert::ToInt32(a->GetValue(i));
        a->SetValue(temp / final, i);
        temp = temp % final;
    }
    return temp;
}
 
bool MyConverter::zero(void)
{
    for(int i=0; i<a->GetLength(0); i++)
    {
        if(Convert::ToInt32(a->GetValue(i)) != 0) return false;
    }
    return true;
}
 
std::string MyConverter::sysToStd(System::String^ SysStr)
{
    char *v = (char*) (Marshal::StringToHGlobalAnsi(SysStr)).ToPointer() ;
    string result = string(v);
    Marshal::FreeHGlobal(System::IntPtr((void*)v));
    return result;
}
В файле-заголовнике:
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
// MyConverterCoreModule.h
#pragma once
#include "stdafx.h"
#include <string>
 
using namespace System;
 
namespace MyConverterCoreModule
{
    public ref class MyConverter
    {
 
    public:
 
        static String^ result;
 
        static bool invalidDigit;
 
        static bool stopme;
 
        static bool zero(void);
 
        static char intToChar(int);
 
        static int charToInt(char);
 
        static int nextNumber(int);
 
        static std::string sysToStd(String^);
 
        static void myconvertWhatFromTo(String^, int, int);
 
    private:
 
        static Array^ a;
 
        static int original;
    };
 
}
Для использования подключить пр-во имен MyConverterCoreModule и вызывать MyConverter::myconvertWhatFromTo(String^ victim, int base1, int base2). Результат будет храниться в MyConverter::result. Процесс может занять много времени, для этого нужна булевая MyConverter::stopme, обратишь ее в правду после вызова myconvertWhatFromTo - в MyConverter::result будет только кусок конвертированного числа. Она неправильно переводит, если в исходной сс нет таких цифр, какие переданы ф-и, для упреждения этого нужна булевая MyConverter::invalidDigit - ее надо проверять после вызова ф-и, не стала ли она правдой.
Как это можно оптимизировать? Для ~20тыщ-значного 16-ричного числа время перевода в 62-сс составляет ~2.5 мин. Это неприемлемо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.08.2015, 14:54
Помогаю со студенческими работами здесь

Получить строку Unicode из массива байт c 00 00 байтами
Есть массив байт в совокупности представляющий строку Unicode (каждый символ кодируется 2-мя байтами), тут пример: 11 22 - 33 44 - 55 66...

Получить UTF8-строку из элементов массива (тип Байт)
Есть одномерный массив байтов (к примеру из десяти элементов). При этом Элемент 1 и Элемент 2 - вместе образуют байты кода UTF8-символа...

Получить обычную строку (string) из массива байт Windows-1251
Здравствуйте! Есть массив byte, содержащий коды символов в кодировке windows-1251 (А=192, я=255). Как из этого массива получить стандартную...

Конвертация С исходников в байт код
Доброго времени суток Существует ли библиотека для Java (нужно, чтобы работало под Андроид), которая бы исходник на С (хотя бы на...

Перевод чисел из десятичной системы счисления в 2-ичную, 8-ричную, 16-ричную и обратно
Помогите составить проги.Очень нато!!!Желательно в процедурах или функциях.


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru