Преобразование строки в гекс с 21 символом

У меня есть служба для интеграции с другим приложением, и она принимает всего 21 шестнадцатеричный символ. Мне нужно передать и получить строку с 11 десятичными символами, например: String s = "0101230154V";

Я хотел бы знать, как я могу использовать операции сдвига для преобразования его в биты и передачи, потому что я не могу преобразовать свою десятичную строку в гексагональную, потому что это приведет к 22 шестнадцатеричным символам. Я пробовал с кодом ниже. Я думаю, что шестнадцатеричное преобразование нормально, но когда я попытался преобразовать обратно в десятичную запись, это не сработало, дайте мне другие значения. Программисты C#, C++ и Java, я думаю, могли бы мне помочь.

int n = 99;  // 2^6 bits to use 99
int k = 999; // 2^9 bits to use 999

int bits = (n << 6) | (k << 9 << 6); // I'm not sure if it is ok to convert and use with hexa

var hexa = bits.ToString("X"); // I will transmit this hexa to a web service

А в другом проекте у меня есть служба Windows для чтения гекса из веб-службы. Я могу читать нормально, но я не знаю, как преобразовать обратно шестнадцатеричное значение и взять значения n и k для примера:

string hexa = GetFromWebService(); // get from the value from the web service here, its fine

// I will recieve the hexa and get the number in bits
int received = Int32.Parse(hexa, System.Globalization.NumberStyles.HexNumber);

// here I need to discover the N and K values... how?

Как узнать значения n и k?

Окончательное решение

long v = 123456789456;
string h = v.ToString("X");

// trasmit h value

var data = long.Parse(hexaValueFromService, System.Globalization.NumberStyles.HexNumber);

благодарю вас


person Felipe Oriani    schedule 08.08.2013    source источник
comment
Ваш вопрос меня немного смущает. Ваш пример String s = "0101230154V"; содержит 11 символов, но последний символ не является десятичным. Это опечатка?   -  person Nolonar    schedule 08.08.2013
comment
Я думаю, что он имел в виду 11 в десятичной системе.   -  person Levente Kurusa    schedule 08.08.2013
comment
Какие символы разрешены в строке? Очевидно, что если у вас может быть 256 опций (или больше), вы не сможете закодировать это в шестнадцатеричной строке длиной менее 22 символов.   -  person Vincent van der Weele    schedule 08.08.2013
comment
Я обновляю свой вопрос, ребята, я думаю, что это проще понять. спасибо   -  person Felipe Oriani    schedule 08.08.2013


Ответы (3)


Я не знаю, есть ли опечатка, когда вы говорите "11 десятичных символов" или нет, потому что последний символ явно не является десятичной или шестнадцатеричной цифрой.

Если это настоящая опечатка, 11 десятичных символов имеют максимальное значение 99 999 999 999, что соответствует 64-битному целому числу, которое соответствует только 16 шестнадцатеричным символам. Таким образом, вы можете преобразовать строку в int64_t (C++)/long (C#/Java), а затем перейти к другой службе.

В случае, если это не опечатка, вы все равно можете преобразовать первые 10 десятичных цифр в int64_t, а затем передать как int64_t, так и оставшийся символ, требуется только 18 шестнадцатеричных символов.

Если вы не хотите преобразовывать в двоичный формат, тогда лучше использовать плотно упакованный десятичный формат (DPD). выбор. Он упаковывает 3 десятичных цифры в 10 бит. Таким образом, для 10 цифр требуется 34 бита, что занимает 9 шестнадцатеричных цифр. Это работает непосредственно с десятичным числом и не требует преобразования в двоичное, поэтому оно не только занимает меньше места, но и очень быстро преобразуется туда и обратно. Если вам не нужно выполнять арифметические действия со значением, это может быть лучшим выбором.

person phuclv    schedule 08.08.2013
comment
Не могли бы вы привести пример? Я действительно нуб с этим типом подхода, хе-хе - person Felipe Oriani; 08.08.2013
comment
что касается вашей строки 0101230154V, 0101230154 = 0x000000000608A64A, V = 0x56 ASCII. Таким образом, вы можете передать строку как 0x000000000608A64A560000. - person phuclv; 08.08.2013

Символ ASCII занимает один байт или 8 бит. Символ Unicode занимает два байта или 16 бит. Поэтому эта строка из 11 символов будет занимать 11 или 22 байта в зависимости от набора символов. Попробуйте установить для набора символов значение ASCII, и это сработает.
При обычном вводе два шестнадцатеричных символа занимают ОДИН байт. Таким образом, ваша служба имеет максимум 90 бит ввода (10,5 байта).

person Levente Kurusa    schedule 08.08.2013
comment
Символ Unicode занимает два байта, что не совсем правильно. Кодировка Unicode UTF-8 кодирует символ в 1,2,3 или 4 байта, UTF-16 - в 2 или 4 байта, а UTF-32 кодирует каждый символ в 4 байта. - person jlordo; 08.08.2013
comment
Я думаю, что Java использует 16-битный набор символов Unicode, но поправьте меня, если я ошибаюсь. - person Levente Kurusa; 08.08.2013
comment
Да, внутри Java используется UTF-16, поэтому каждый символ кодируется 2 или 4 байтами (младшим и старшим суррогатом). - person jlordo; 08.08.2013
comment
Я обновляю свой вопрос, ребята, я думаю, что это проще понять. спасибо - person Felipe Oriani; 08.08.2013
comment
Не совсем, я еще больше растерялся, если честно. - person Levente Kurusa; 08.08.2013
comment
Нет способа преобразовать обратно, чтобы получить значение n и k из переменной received? - person Felipe Oriani; 08.08.2013
comment
Вы их устанавливаете, зачем они вам обратно? - person Levente Kurusa; 08.08.2013
comment
Я имею в виду, что это другая область... первая часть находится на удаленном оборудовании и передается в веб-службу. Я получу в службе Windows, и мне нужно преобразовать обратно. - person Felipe Oriani; 08.08.2013

Вы можете гарантировать, что символ не будет отображаться в первых двух цифрах? если да, то можно подставить в k целое число из первых 2-х цифр.

если вы оставили сдвиг для подавления начальных «0» во время прохождения, как только вы его получите, у вас снова будет сдвиг вправо, чтобы получить исходное число, а не анализировать целое число. например: если вы сделаете это:

(n — 6 бит, а k — 9 бит), поэтому вы хотите объединить их в биты (15 бит, 16-й бит — знаковый бит, поэтому не будем использовать это)

int bits =   (k << 6) | n

когда вы получаете, вы должны сделать это, чтобы получить значения:

n = (bits & 0x3F)     // gets rid of k in the first part 0x3F means '0000000000111111'
k = (bits >> 6)       // gets rid of n at the bottom part
person Zia    schedule 08.08.2013
comment
Привет друг, спасибо за ваш ответ. Я проверяю это, и k идет нормально, а n нет. Почему k 10 бит, а не 9? - person Felipe Oriani; 08.08.2013
comment
с 9 битами вы можете дойти до 512. вам нужно 10 бит, чтобы дойти до 999. Мой ответ все равно изменился, потому что мы не должны использовать 16-й бит, который является битом знака; также нужно 7 бит, чтобы увеличить до 99. попробуйте сейчас - person Zia; 08.08.2013
comment
Странно, n равно 35, а k равно 999 (хорошо). Я меняю начальные значения n на 12 и k на 452.. и оба работают нормально, когда n равно 99 (максимально возможное значение), получается 35.. - person Felipe Oriani; 08.08.2013
comment
как я уже сказал, вы можете подняться до 63 и 511 с 6 и 9 битами соответственно... для 99 и 999 вам нужны 7 и 10 бит соответственно. Вы можете использовать 99 и 99 в n и k? тогда вам нужно 7 + 7 = 14 бит и легко сделать в типе int. в этом случае int bits = (k ‹‹ 7) | н; n=(биты и 0x7F) ; k= бит ›› 7 - person Zia; 08.08.2013
comment
Максимально возможное значение для n равно 99, а k равно 999. Вот почему я пытаюсь использовать эти значения. Я проверил это: int bits = (k << 7) | n; и преобразовал: n= (bits & 255); k = bits >> 7. Я получаю все значения в порядке, но я не знаю, почему 255, потому что 255 - это 2 ^ 7-1 (-1, потому что знак)? - person Felipe Oriani; 08.08.2013
comment
двоичный код числа 255 — «0000 0000 0111 1111» (16-битный формат). Поэтому, когда вы выполняете побитовую операцию &, остаются только последние 7 битов, а остальные 9 битов превращаются в нули. надеюсь это поможет. - person Zia; 08.08.2013
comment
Спасибо, Зия, я одобрю ваш awnser, но еще вопрос, если у меня есть другое значение b = 2359 для образца, как я могу объединить это значение с другими n и k, должен ли я использовать оператор | и << для чего? еще раз спасибо! - person Felipe Oriani; 08.08.2013
comment
для конкатенации вы должны сначала преобразовать целое число в строку, а затем выполнить конкатенацию строк. | или ‹‹ не помогут, потому что они манипулируют битами, а не строками. - person Zia; 08.08.2013