Сложение 16ричных чисел

xatchikzzz

Client
Регистрация
08.09.2010
Сообщения
566
Благодарностей
38
Баллы
28
Подскажите кто знает как это можно реализовать??
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 691
Баллы
113

xatchikzzz

Client
Регистрация
08.09.2010
Сообщения
566
Благодарностей
38
Баллы
28
перевести в 10-тиричные, сложить, перевести обратно
допустим даже такой вариан )) но если цифры будут огромные что даже в калькулятор не влазиют ...

а в 16 рично системе будет всего лишь 3b567c2314a545bb4

поэтому подходит вариант именно работы в 16 ричной системе ...
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 691
Баллы
113

Sherminator

Client
Регистрация
10.09.2021
Сообщения
1 011
Благодарностей
539
Баллы
113
допустим даже такой вариан )) но если цифры будут огромные что даже в калькулятор не влазиют ...

а в 16 рично системе будет всего лишь 3b567c2314a545bb4

поэтому подходит вариант именно работы в 16 ричной системе ...
Недавно тема была, сюда число вообще любой длинны можно засунуть, только в коде умножение на сложение надо заменить.
 

xatchikzzz

Client
Регистрация
08.09.2010
Сообщения
566
Благодарностей
38
Баллы
28
Недавно тема была, сюда число вообще любой длинны можно засунуть, только в коде умножение на сложение надо заменить.
там немного не то, там же в 10 все .. (91389681247993671255432112000000 ) а как его потом перевести в 16 ричную систему там все калькуляторы афигели просто от значения )

Ну и на оборот как 16 ричное число перевести в 10 чтоб было полное число .. чтоб узнать от какого числа стартовать
 
Последнее редактирование:

Sherminator

Client
Регистрация
10.09.2021
Сообщения
1 011
Благодарностей
539
Баллы
113
там немного не то, там же в 10 все .. (91389681247993671255432112000000 ) а как его потом перевести в 16 ричную систему там все калькуляторы афигели просто от значения )

Ну и на оборот как 16 ричное число перевести в 10 чтоб было полное число .. чтоб узнать от какого числа стартовать
Да в целом конвертацию из одной системы в другую проводить не так сложно

C#:
            int a = 6357452;
            string result;

            result = Convert.ToString(a, 16);
Вот пример кода для перевода в 16, другое дело что у тебя число слишком длинное)
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 691
Баллы
113
другое дело что у тебя число слишком длинное)
надо просто разделить число на разряды и при переводе умножать или делить на эти самые разряды.
например 1700000 это 19f0a0
если отбросить первые 2 разряда, то это 19f0 и a0 , соответственно при конвертации умножаем 19f0 на 16^2 + a0 получим обратно 1700000
и так можно делать с любыми сколько угодными большими числами.
но думаю можно просто обойтись double , тем более что Convert принимает много больших форматов
 
  • Спасибо
Реакции: djaga

xatchikzzz

Client
Регистрация
08.09.2010
Сообщения
566
Благодарностей
38
Баллы
28
Да в целом конвертацию из одной системы в другую проводить не так сложно

C#:
            int a = 6357452;
            string result;

            result = Convert.ToString(a, 16);
Вот пример кода для перевода в 16, другое дело что у тебя число слишком длинное)
вот и я том же что число большое ... но перевести ег онадо .. в идеале было просто отработат ьсложение 2 шеснадцатиричных чисел и все ..
 

xatchikzzz

Client
Регистрация
08.09.2010
Сообщения
566
Благодарностей
38
Баллы
28
никто не знает как это реализовать ... сложение 16 ричных чисел?
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 681
Благодарностей
1 864
Баллы
113

xatchikzzz

Client
Регистрация
08.09.2010
Сообщения
566
Благодарностей
38
Баллы
28

Sherminator

Client
Регистрация
10.09.2021
Сообщения
1 011
Благодарностей
539
Баллы
113
интерисует вариант без перевода в десятичную .. именно сложение шестнадцатиричных значений надо

3b567c2314a545bb4+6f4d444ab
Я вопрос погуглил, по форумам по c# полазал, везде сначала в 10 переводят а потом складывают.
 

xatchikzzz

Client
Регистрация
08.09.2010
Сообщения
566
Благодарностей
38
Баллы
28
а как мо
Я вопрос погуглил, по форумам по c# полазал, везде сначала в 10 переводят а потом складывают.
а как можно перевести 3b567c2314a545bb4 в десятичное значение чтоб получить полный ответ ... без -e
 

Sherminator

Client
Регистрация
10.09.2021
Сообщения
1 011
Благодарностей
539
Баллы
113

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 765
Благодарностей
2 407
Баллы
113
интерисует вариант без перевода в десятичную .. именно сложение шестнадцатиричных значений надо

3b567c2314a545bb4+6f4d444ab
Вы не указали, какой результат ожидаете.
Что должно получиться на выходе, после сложения этих двух строк?

Собственно, данную задачу я бы для себя решал примерно так:
Сначала выровнял бы размер строк, дополнив их нулями слева.
Дальше, то что получилось - перевел бы в двоичный код.
Дальше уже произвел бы суммирование каждого разряда.
Дальше результат преобразовал бы в байты.
Ну, и в конечном итоге - байты обратно вернул бы в виде хеш строки.

Таким образом, мне не важно было бы выходит за диапазон чисел или нет - работал бы с подобными данными просто как с обычными строками.
Пример набросал, возможно он как-то поможет.

C#:
Func<string, string> GetBinary = (hex) =>{  
    hex = hex.Replace(" ", string.Empty);
    hex = hex.Replace("-", string.Empty);
    hex = hex.Trim();
    if((hex.Length % 2) > 0) hex = hex.PadLeft(hex.Length + 1, '0');
    var bin = new StringBuilder();
    for(var i = 0; i < hex.Length/2; i++){
       bin.Append(Convert.ToString(Convert.ToByte(hex.Substring(i * 2, 2), 16), 2).PadLeft(8, '0'));
    }
    return bin.ToString();
};

Func<string, string, string> Sum = (x, y)=>{
    int max = x.Length > y.Length ? x.Length : y.Length;
    if(max%2>0) max++;
    max += 2;
    x = x.PadLeft(max, '0');
    y = y.PadLeft(max, '0');

    var list = new List<int>();
    int z = 0;
    for (int i = y.Length - 1; i >= 0; --i) {
        int b1 = x[i] - '0';
        int b2 = y[i] - '0';
        list.Add((b1 ^ b2 ^ z) + '0');
        z = (b1&z)|(b2&z)|(b1&b2);
    }
    if(z == 1) list.Add(z);      
    list.Reverse();

    return new String(list.Select(m=>(char)m).ToArray());
};

Func<string, string> ConvertToByte = (s) =>{
    int size = s.Length / 8;
     var sb = new StringBuilder();
    for(int i = 0; i < size; ++i) {
         sb.Append( Convert.ToByte(s.Substring(8 * i, 8), 2).ToString("X2"));
    }
    return sb.ToString();
};

// Здесь начинается магия...
string line1 = "03-b5-67-c2-31-4a-54-5b-b4";
string line2 = "06 f4 d4 44 ab";


string a = GetBinary(line1);
project.SendInfoToLog(string.Format("{0} {1}", line1, a));

string b = GetBinary(line2);
project.SendInfoToLog(string.Format("{0} {1}", line2, b));

string sum = Sum(a,b);
string hash = ConvertToByte(sum);

project.SendInfoToLog(string.Format("{0} {1}", hash, sum));
95055


P.S. Код рассматривать исключительно как пример, я где-то допустил ошибку в процессе перевода значений, из-за чего результат может быть не корректным. Идея была объяснить базовый принцип.
 
Последнее редактирование:

xatchikzzz

Client
Регистрация
08.09.2010
Сообщения
566
Благодарностей
38
Баллы
28
Вы не указали, какой результат ожидаете.
Что должно получиться на выходе, после сложения этих двух строк?

Собственно, данную задачу я бы для себя решал примерно так:
Сначала выровнял бы размер строк, дополнив их нулями слева.
Дальше, то что получилось - перевел бы в двоичный код.
Дальше уже произвел бы суммирование каждого разряда.
Дальше результат преобразовал бы в байты.
Ну, и в конечном итоге - байты обратно вернул бы в виде хеш строки.

Таким образом, мне не важно было бы выходит за диапазон чисел или нет - работал бы с подобными данными просто как с обычными строками.
Пример набросал, возможно он как-то поможет.

C#:
Func<string, string> GetBinary = (hex) =>{ 
    hex = hex.Replace(" ", string.Empty);
    hex = hex.Replace("-", string.Empty);
    hex = hex.Trim();
    if((hex.Length % 2) > 0) hex = hex.PadLeft(hex.Length + 1, '0');
    var bin = new StringBuilder();
    for(var i = 0; i < hex.Length/2; i++){
       bin.Append(Convert.ToString(Convert.ToByte(hex.Substring(i * 2, 2), 16), 2).PadLeft(8, '0'));
    }
    return bin.ToString();
};

Func<string, string, string> Sum = (x, y)=>{
    int max = x.Length > y.Length ? x.Length : y.Length;
    if(max%2>0) max++;
    max += 2;
    x = x.PadLeft(max, '0');
    y = y.PadLeft(max, '0');

    var list = new List<int>();
    int z = 0;
    for (int i = y.Length - 1; i >= 0; --i) {
        int b1 = x[i] - '0';
        int b2 = y[i] - '0';
        list.Add((b1 ^ b2 ^ z) + '0');
        z = (b1&z)|(b2&z)|(b1&b2);
    }
    if(z == 1) list.Add(z);     
    list.Reverse();

    return new String(list.Select(m=>(char)m).ToArray());
};

Func<string, string> ConvertToByte = (s) =>{
    int size = s.Length / 8;
     var sb = new StringBuilder();
    for(int i = 0; i < size; ++i) {
         sb.Append( Convert.ToByte(s.Substring(8 * i, 8), 2).ToString("X2"));
    }
    return sb.ToString();
};

// Здесь начинается магия...
string line1 = "03-b5-67-c2-31-4a-54-5b-b4";
string line2 = "06 f4 d4 44 ab";


string a = GetBinary(line1);
project.SendInfoToLog(string.Format("{0} {1}", line1, a));

string b = GetBinary(line2);
project.SendInfoToLog(string.Format("{0} {1}", line2, b));

string sum = Sum(a,b);
string hash = ConvertToByte(sum);

project.SendInfoToLog(string.Format("{0} {1}", hash, sum));
Посмотреть вложение 95055

P.S. Код рассматривать исключительно как пример, я где-то допустил ошибку в процессе перевода значений, из-за чего результат может быть не корректным. Идея была объяснить базовый принцип.
ответ хотело сь бы тоже в 16 ричной системе получить ...
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 691
Баллы
113

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 765
Благодарностей
2 407
Баллы
113
ответ хотело сь бы тоже в 16 ричной системе получить ...
Конкретное значение указать нужно, так как онлайн калькуляторы обрезают и показывают не корректно.
Код ниже должен быть корректным (но, проверять надо, а чтобы проверить - нужно знать что именно должно быть на выходе).

В том сообщении в коде ошибка. Я не перепроверил что длина строки 0100010101 кратна 8. В итоге, получалось что перевод в байты работал со смещением, что и выдавало не корректный результат.
Исправил этот момент добавлением нескольких нулей спереди, чтобы сделать длину строки кратной 8.
После чего - все вроде заработало корректно.
Сюда добавлю исправленную версию:
C#:
Func<string, string> GetBinary = (hex) =>{
    hex = hex.Replace(" ", string.Empty);
    hex = hex.Replace("-", string.Empty);
    hex = hex.Trim();
    if((hex.Length % 2) > 0) hex = hex.PadLeft(hex.Length + 1, '0');
    var bin = new StringBuilder();
    for(var i = 0; i < hex.Length/2; i++){
       bin.Append(Convert.ToString(Convert.ToByte(hex.Substring(i * 2, 2), 16), 2).PadLeft(8, '0'));
    }
    return bin.ToString();
};

Func<string, string, string> Sum = (x, y)=>{
    int max = x.Length > y.Length ? x.Length : y.Length;
    if(max%2>0) max++;
    max += 2;
    x = x.PadLeft(max, '0');
    y = y.PadLeft(max, '0');

    var list = new List<int>();
    int z = 0;
    for (int i = y.Length - 1; i >= 0; --i) {
        int b1 = x[i] - '0';
        int b2 = y[i] - '0';
        list.Add((b1 ^ b2 ^ z) + '0');
        z = (b1&z)|(b2&z)|(b1&b2);
    }
    if(z == 1) list.Add(z);   
    list.Reverse();
    string temp = new String(list.Select(m=>(char)m).ToArray());
    if((temp.Length%8)>0) temp=temp.PadLeft((temp.Length/8+1)*8, '0');
    return temp;
};

Func<string, string> ConvertToByte = (s) =>{
    int size = s.Length / 8;
     var sb = new StringBuilder();
    for(int i = 0; i < size; ++i) {
         sb.Append( Convert.ToByte(s.Substring(8 * i, 8), 2).ToString("X2"));
    }
    return sb.ToString();
};

// Здесь начинается магия...
string line1 = "03b567c2314a545bb4";
line1 = "fff";
string line2 = "06f4d444ab";
line2 = "aaa";


string a = GetBinary(line1);
project.SendInfoToLog(string.Format("{0} {1}", line1, a));

string b = GetBinary(line2);
project.SendInfoToLog(string.Format("{0} {1}", line2, b));

string sum = Sum(a,b);
string hash = ConvertToByte(sum);

project.SendInfoToLog(string.Format("{0} {1}", hash, sum));
Вот два варианта.
По первому онлайн калькулятор показывает:
95064

95062


По второму калькулятор показывает:

95065

95063


В итоге - есть где-то шибка или нет - нужно понять что должно быть на выходе (желаемый результат, и уже относительно этого править решение).

P.S. Перепроверил руками - выглядит так, что мой код работает лучше чем онлайн калькулятор.
 
Последнее редактирование:

ebrwebrw

Client
Регистрация
20.08.2018
Сообщения
221
Благодарностей
163
Баллы
43
гугл

using System.Numerics;
using System.Globalization;

C#:
BigInteger bi1 = BigInteger.Parse("3b567c2314a545bb4", NumberStyles.HexNumber);
BigInteger bi2 = BigInteger.Parse("6f4d444ab", NumberStyles.HexNumber);
BigInteger sum = BigInteger.Add(bi1, bi2);
Console.WriteLine("{0:x}", sum); //or sum.ToString("x")
так тоже 3b567c2383f28a05f


только вот при сложении "fff" и "aaa" выдает aa9, без 1 в начале, хотя онлайн калькуляторы выдают 1aa9

UPD
нужно дописывать 0 в начало, что бы было 0fff и 0aaa допустим, тогда результат так же 1aa9 получается
 
Последнее редактирование:
  • Спасибо
Реакции: BAZAg

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 765
Благодарностей
2 407
Баллы
113
гугл

using System.Numerics;
using System.Globalization;

C#:
BigInteger bi1 = BigInteger.Parse("3b567c2314a545bb4", NumberStyles.HexNumber);
BigInteger bi2 = BigInteger.Parse("6f4d444ab", NumberStyles.HexNumber);
BigInteger sum = BigInteger.Add(bi1, bi2);
Console.WriteLine("{0:x}", sum); //or sum.ToString("x")
так тоже 3b567c2383f28a05f


только вот при сложении "fff" и "aaa" выдает aa9, без 1 в начале, хотя онлайн калькуляторы выдают 1aa9
Так из-за этого я и написал чтобы человек уточнил что именно ему нужно на выходе - чтобы понять какой вариант можно считать правильным.
 

ebrwebrw

Client
Регистрация
20.08.2018
Сообщения
221
Благодарностей
163
Баллы
43
Так из-за этого я и написал чтобы человек уточнил что именно ему нужно на выходе - чтобы понять какой вариант можно считать правильным.
то да, я несколько онлайн калькуляторов глянул, там почти на всех разный результат был по 3b567c2314a545bb4+6f4d444ab

и только на одном из всех был как у тебя или в том коде что я скинул
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 765
Благодарностей
2 407
Баллы
113
то да, я несколько онлайн калькуляторов глянул, там почти на всех разный результат был по 3b567c2314a545bb4+6f4d444ab

и только на одном из всех был как у тебя или в том коде что я скинул
Я также разные поглядел, понял что они обрезают (переводят например в десятичную, складывают, возвращают результат, но сталкиваются с переполнением, из-за чего что-то да пропадает).
В конечном итоге взял бумажку, ручку и на листике сосчитал сумму, после чего уже сравнил с кодом.
 
  • Спасибо
Реакции: xatchikzzz и ebrwebrw

xatchikzzz

Client
Регистрация
08.09.2010
Сообщения
566
Благодарностей
38
Баллы
28
Я также разные поглядел, понял что они обрезают (переводят например в десятичную, складывают, возвращают результат, но сталкиваются с переполнением, из-за чего что-то да пропадает).
В конечном итоге взял бумажку, ручку и на листике сосчитал сумму, после чего уже сравнил с кодом.
1AA9 это верный вариант сложения FFF +AAA

буду дома затестю посмотрю как в работе будет ! спасибо!
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)