Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
 Аватар для bedvit
1209 / 260 / 22
Регистрация: 20.05.2016
Сообщений: 1,139
Записей в блоге: 22

Быстрые алгоритмы сборки байтового массива в строку и наоборот

19.07.2016, 12:28. Показов 2898. Ответов 50
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет! Народ не поделитесь быстрым алгоритмом сборки байтового массива из строки (только цифры) и разборки массива в строку?
К примеру:
VB.NET
1
2
dim s as string = "11111111111111111111111111111111111"
dim b as byte = {199,113,28,199,25,215,128,175,156,8,79,240,209,35,2} ' (прямой порядок байтов, от низшего до старшего байта).
т.е. s=2*(28)14*+ 35*(28)13*+ 209*(28)12*+ …+199*(28)0
s->b
b->s
Пишу на Vb, но и в С#разберусь, если будет алгоритм.

Спасибо!
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.07.2016, 12:28
Ответы с готовыми решениями:

Быстрые алгоритмы нахождения чисел-палиндромов на заданном промежутке
Какие существуют быстрые алгоритмы нахождения палиндромов на промежутке?

Какие есть самые лучшие алгоритмы сортировки, самые быстрые?
Подскажите пожалуйста, какие есть самые лучшие алгоритмы сортировки, самые быстрые. Например есть одномерный массив чисел, как его быстро...

Шифрование в DPAPI байтового массива
Есть код шифрования строки "Мой Мир" при помощи DPAPI string text = "Мой Мир"; string entropy =...

50
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
19.07.2016, 13:31
Можно сделать, к примеру, вот так:
C#
1
Console.WriteLine(new BigInteger(new byte[] { 199, 113, 28, 199, 25, 215, 128, 175, 156, 8, 79, 240, 209, 35, 2, 0 }).ToString());
Ноль в конец добавлен для того, чтобы не получилось отрицательное значение.

Добавлено через 4 минуты
Обратно:
C#
1
Console.WriteLine(string.Join(", ", BigInteger.Parse("11111111111111111111111111111111111").ToByteArray()));
1
 Аватар для bedvit
1209 / 260 / 22
Регистрация: 20.05.2016
Сообщений: 1,139
Записей в блоге: 22
19.07.2016, 14:02  [ТС]
Именно от BigInteger и хотел отказаться А так же от BitConverter . GetBytes.
Ибо на больших массивах, как мне показалось работает не настолько быстро, как хотелось.
Свои алгоритмы пока успеха не принесли, вот и решил обратится к форуму.

Добавлено через 33 секунды
Но за ответ +Спасибо!
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
19.07.2016, 14:36
Большие числа приходится по многу раз делить и умножать, вот оно и считается долго.
Можно попробовать вручную реализовать длинную арифметику:
Википедия: Позиционная система счисления/Переход к другому основанию
/Перевод в десятичную систему счисления

Только сомневаюсь, что это будет быстрее.

Добавлено через 4 минуты
Вот такое ещё нашлось:
Википедия: Длинная арифметика/Алгоритмы преобразования системы счисления

Так что некоторый шанс ускорить код всё же есть (если авторы .NET выбрали для BigInteger неоптимальные алгоритмы)
0
296 / 259 / 107
Регистрация: 26.10.2012
Сообщений: 809
19.07.2016, 14:45
Так как-то наверное
символы '0'-'9' кодируются в байты {48, 0} - {57, 0}
поэтому изменяем только четные байты массива
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        byte[] StringToByteArray(string source)
        {
            var bytes = new byte[source.Length << 1];
            for (var i = 0; i < bytes.Length; i += 2)
            {
                bytes[i] = (byte) source[i>>1];
            }
            return bytes;
        }
 
        string ByteArrayToString(byte[] bytes)
        {
            var sb = new StringBuilder(bytes.Length >> 1);
            for (var i = 0; i < bytes.Length; i += 2) sb.Append((char) bytes[i]);
            return sb.ToString();
        }
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
19.07.2016, 14:52
jetyb, эти функции дадут совершенно другой результат.
bedvit, обязательно использовать именно десятичную систему счисления? для двоичной или восьмеричной, к примеру, можно сделать намного более быстрое решение.
0
 Аватар для bedvit
1209 / 260 / 22
Регистрация: 20.05.2016
Сообщений: 1,139
Записей в блоге: 22
19.07.2016, 15:25  [ТС]
Входящие/исходящие данные десятичные (строка), а в остальном можно любую систему счисления. Вопрос в преобразовании, сколько это времени займет.
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
19.07.2016, 15:35
Если всё равно что будет в массиве, тогда достаточно написать
C#
1
Encoding.ASCII.GetBytes("11111111111111111111111111111111111")
Это будет близко к варианту от jetyb.
Можно ещё в два раза сжать - но будет чуть дольше.
0
 Аватар для bedvit
1209 / 260 / 22
Регистрация: 20.05.2016
Сообщений: 1,139
Записей в блоге: 22
19.07.2016, 16:06  [ТС]
Vort_, Спасибо! Попробовал. Прошу прощения, но видимо я вас ввел в заблуждение, видимо без десятичной системы не обойтись - дальше с массивом планируется математика. На самом деле массив "b" содержит коэффициенты разложения длинного числа/строки с основанием 28. Поскольку со степенью двойки легче работать на низком уровне (умножение и деление на степень двойки соответствует битовым сдвигам влево и вправо)

Добавлено через 7 минут
Для понимания: вообщем-то я делаю математику для объекта похожего на структуру BigInteger, но с другим основанием и своими методами и свойствами.
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
19.07.2016, 16:22
Цитата Сообщение от bedvit Посмотреть сообщение
Для понимания: вообщем-то я делаю математику для объекта похожего на структуру BigInteger, но с другим основанием и своими методами и свойствами.
Каким таким другим? BigInteger внутри хранит всё в двоичной системе счисления, так как компьютеры оптимизированы именно для работы с двоичным представлением. Что-либо другое, скорее всего, будет менее оптимально.
Если же имеется в виду основание входных и выходных данных (строки), то его поддержку вполне можно добавить к уже существующему коду BigInteger (сделав наследника класса, к примеру).
Туда же можно дописать и новые, специфичные, методы.
0
 Аватар для bedvit
1209 / 260 / 22
Регистрация: 20.05.2016
Сообщений: 1,139
Записей в блоге: 22
19.07.2016, 16:43  [ТС]
BigInteger это структура, у структуры нет наследников (насколько я знаю)
BigInteger сидит на основании 232
Для 64-х разрядной структуры оптимальное основание будет 264.
+быстрее.

Добавлено через 36 секунд
Если только делать интерфейсы, но это не подходит.

Добавлено через 9 минут
Если интересно:
https://habrahabr.ru/post/207754/
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
19.07.2016, 16:49
Цитата Сообщение от bedvit Посмотреть сообщение
BigInteger это структура, у структуры нет наследников (насколько я знаю)
Не учёл этот момент.
Цитата Сообщение от bedvit Посмотреть сообщение
BigInteger сидит на основании 232
Для 64-х разрядной структуры оптимальное основание будет 264.
+быстрее.
В таком случае можно взять официальные исходники и подправить по своему вкусу
Reference Source: BigInteger.cs
1
 Аватар для bedvit
1209 / 260 / 22
Регистрация: 20.05.2016
Сообщений: 1,139
Записей в блоге: 22
19.07.2016, 18:06  [ТС]
Надо же, открытая инфа, я думал это закрытий-лицензионный продукт.
Поэтому пришлось тупо декомпелировать из системы (.NET Reflector в помощь)
Зато сразу в VB.NET, С# - похуже знаю.
За ссылку спасибо, пригодится!
Кода много, решил что сам быстрее соберу, зная принципы.

Добавлено через 47 минут
Но быстрым этот процесс не назовешь, + думал с помощью форума пойдет побыстрее
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
19.07.2016, 18:14
Цитата Сообщение от bedvit Посмотреть сообщение
Но быстрым этот процесс не назовешь, + думал с помощью форума пойдет побыстрее
Но ведь и задача - сделать алгоритм быстрее, чем у Microsoft - непростая.
0
 Аватар для bedvit
1209 / 260 / 22
Регистрация: 20.05.2016
Сообщений: 1,139
Записей в блоге: 22
19.07.2016, 18:16  [ТС]
Да, ради этого, вообщем и весь замес Обернуть структуру в свой класс, не проблема, но зачем изобретать велосипед - если он есть. Вот если мотоцикл - и поехать побыстрее - смысл есть.
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
19.07.2016, 18:20
Я, кстати, вижу ещё два варианта.
1. Поискать сторонние .NET библиотеки для длинной арифметики. Учитывая, что уже есть BigInteger - врядли кто-то будет такое создавать. Но мало ли.
2. Найти C++ библиотеки и постараться их подключить к .NET`у. Может стать быстрее, может медленнее. Но явно ухудшится переносимость программы.
0
 Аватар для bedvit
1209 / 260 / 22
Регистрация: 20.05.2016
Сообщений: 1,139
Записей в блоге: 22
19.07.2016, 18:28  [ТС]
Есть вот такая штука, но я пока не разобрался, что с ней можно сделать.
И вот такая (помедленнее но на C#!).
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
20.07.2016, 08:19
Лучший ответ Сообщение было отмечено bedvit как решение

Решение

Вот пример моего пункта #2:
Mpir.NET
C#
1
Console.WriteLine(string.Join(", ", new mpz_t("11111111111111111111111111111111111").ToByteArray(-1)));
Добавлено через 13 часов 23 минуты
Похоже, это решение - то, что надо.
Я сделал тестовую программу.
На ней Mpir показывает скорость в 100 раз большую, чем BigInteger.
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
using System;
using System.Numerics;
using System.Text;
using System.Diagnostics;
using System.Linq;
using Mpir.NET;
 
namespace ConsoleApplication25
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 10000;
            var r = new Random(123456);
            var sb = new StringBuilder();
            for (int i = 0; i < n; i++)
                sb.Append((char)(r.Next(10) + '0'));
            string s = sb.ToString();
 
            Console.WriteLine("Test with " + n + " digits:");
            Console.WriteLine();
 
            var sw = new Stopwatch();
            sw.Start();
            byte[] r1 = new mpz_t(s).ToByteArray(-1);
            sw.Stop();
 
            Console.WriteLine("MPIR       : " + sw.ElapsedMilliseconds + " ms");
 
            sw.Start();
            byte[] r2 = BigInteger.Parse(s).ToByteArray();
            sw.Stop();
 
            Console.WriteLine("BigInteger : " + sw.ElapsedMilliseconds + " ms");
 
            Console.WriteLine();
            Console.WriteLine("Test " + (Enumerable.SequenceEqual(r1, r2) ? "OK" : "Fail"));
        }
    }
}
Вот результаты для моего компьютера:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Test with 10000 digits:
MPIR       : 60 ms
BigInteger : 70 ms
Test with 50000 digits:
MPIR       : 66 ms
BigInteger : 256 ms
Test with 100000 digits:
MPIR       : 65 ms
BigInteger : 865 ms
Test with 500000 digits:
MPIR       : 85 ms
BigInteger : 35617 ms
Test with 1000000 digits:
MPIR       : 117 ms
(надоело ждать)
Test with 5000000 digits:
MPIR       : 396 ms
(...)
Test with 10000000 digits:
MPIR       : 814 ms
(...)
0
 Аватар для bedvit
1209 / 260 / 22
Регистрация: 20.05.2016
Сообщений: 1,139
Записей в блоге: 22
20.07.2016, 10:07  [ТС]
Результаты впечатляют! Теперь надо разобраться как это реализовать в .net, что бы не подключать Mpir.
0
 Аватар для Vort_
200 / 200 / 78
Регистрация: 10.07.2012
Сообщений: 409
20.07.2016, 10:36
Цитата Сообщение от bedvit Посмотреть сообщение
Теперь надо разобраться как это реализовать в .net, что бы не подключать Mpir.
Чтобы оценить масштаб проблемы, достаточно глянуть файлы mpn\generic\set_str.c и mpn\generic\mul.c.
Тут и без ассемблерных вставок разобраться непросто. Я, к примеру, стал бы в этом копаться только при очень большой необходимости.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.07.2016, 10:36
Помогаю со студенческими работами здесь

Неверное отображение байтового массива
Всем привет. Я хочу открыть рисунок, конвертнуть его в байтовый массив, и по идеи он должен совпадать с размером самого рисунка. Но не тут...

Преобразование динамического байтового массива в SafeArray
Здравствуйте товарищи! В общем такая проблема, есть рабочая функция, которая преобразовывает байтовые массивы в PSafeArray. Но она работает...

Создание байтового массива с помощью MemCopy, RtlMoveMemory
Замучался экспериментировать. Помогите, пжлста. Есть байтовый массив a, как с помощью MemCopy или RtlMoveMemory создать новый...

Используя указатель на строку, переписать строку в ДРП наоборот
предусмотреть контроль за размером динамически распределяемой памяти (ДРП), а также ее освобождение после выполнения необходимых действий....

Не работает код (программа считывает из файла строку, убирает лишние пробелы и записывает в другой файл строку, словами наоборот)
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;string&gt; #include &lt;algorithm&gt; using namespace std; string...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru