Re: Строковый вектор инициализации

Письмо получил. Завтра задам вопрос коллегам. Может чего и придумаем.

Re: Строковый вектор инициализации

Судя по всему, решение найдено.

Дело в том, что в Embarcadero RAD Studio строки кодируются в unicode. Соответственно, в нашем случае, для корректного расшифрования в C# вектор "11111111" должен быть представлен unicode-строкой (или, для очевидности, "1\01\01\01\0")

Попробуйте так:

            Int64 initVectorGS2 = FromStringToInt64("1\01\01\01\0");
            RetCode = GrdApi.GrdCrypt(GrdHandle,
                                               GrdAN.GSII64,
                                               bArr,
                                               (UInt32)GrdAM.OFB + (UInt32)GrdAM.Decode,
                                               initVectorGS2);

Re: Строковый вектор инициализации

Алексей Перепелов пишет:

.......unicode-строкой (или, для очевидности, "1\01\01\01\0")

"11111111" в юникоде "4949494949494949", как Вы получили из "11111111"-> "1\01\01\01\0" ?

Re: Строковый вектор инициализации

Нет, Дмитрий, Вы не правы.

Строка "11111111" в unicode выглядит как 0x31 0x00 0x31 0x00 0x31 0x00 ....

См. таблицу символов unicode.

Re: Строковый вектор инициализации

Алексей Перепелов пишет:

...выглядит как 0x31 0x00 0x31 0x00 0x31 0x00 ....

нужно было еще в 16-ый вид перевести:

.......
            string unicodeVector = "";
            UnicodeEncoding unicode = new UnicodeEncoding();
            Byte[] b = unicode.GetBytes(sInitVector);
            foreach (byte bb in b)
            {
                unicodeVector = unicodeVector + string.Format("{0:x}", bb);//получаем 16-ное представление unicoda
            }
...........

в итоге получаем unicodeVector=310310310310310310310310, перед расшифровкой данных передаем его в FromStringToInt64(), где получаем исключение в строке:

.....e.GetBytes(szInitVectorGS2, 0, szInitVectorGS2.Length, v, 0);.......

Буфер выходных байт не достаточен для хранения закодированных данных,
кодирование "US-ASCII" резерв "System.Text.EncoderReplacementFallback".
Имя параметра: bytes

Re: Строковый вектор инициализации

Дмитрий,
когда я говорил о том, как выглядит юникод строка из единиц, я имел в виду ее представление в памяти.
Вместо использования FromStringToInt64("1\01\01\01\0") можете сразу присвоить Int64 initVectorGS2 = 0x0031003100310031.

Более длинным (как Ваш unicodeVector) делать вектор инициализации не имеет смысла, так как реально используются только первые 8 байт (согласно документации).

Что касается других вопросов по программированию, то лучше чем я ответы на них подскажет MSDN.

(2011-05-18 17:32:17 отредактировано Dmitriy)

Re: Строковый вектор инициализации

Алексей Перепелов пишет:

Int64 initVectorGS2 = 0x0031003100310031

Наконец расшифровалась строка!!!!! Огромнейшая благодарность от нашей команды разработчиков! Остались некоторые неясности:
1- "1" в unicode это 0031 - вопросов тут нет.
Не могу найти логику преобразования 11111111 = 1\01\01\01\0 or 0x0031003100310031???
                                                                            |________________________________|                 
                                                                                                           V                           
                                                                                                 каким образом                 
                                                                                  получаются такие форматы значений?
вариант с видом "0031003100310031" - вектор 8ми байтный, но unicode каждый символ 2-ух байтный,выходит используем 1-е 4 символа, не ясно тогда как Вы пришли к виду "1\01\01\01\0"?
2-откуда Вы взяли алгоритм по преобразованию строки в int64 (Int64 result = v[0] * ((Int64)1 << 0) + v[1] * ((Int64)1 << 8) + v[2] * ((Int64)1 << 16) + v[3] * ((Int64)1 << 24) + v[4] * ((Int64)1 << 32) + v[5] * ((Int64)1 << 40) + v[6] * ((Int64)1 << 48) + v[7] * ((Int64)1 << 56);)?

Re: Строковый вектор инициализации

1.

ACSII:

'1' == 0x31
'\0' == 0x00
"11111111" == 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x00
"1\01\01\01\0" == 0x31 0x00 0x31 0x00 0x31 0x00 0x31 0x00 0x00 

unicode:

'1' == 0x0031 == 0x31 0x00 
"1111" == 0x31 0x00 0x31 0x00 0x31 0x00 0x31 0x00 0x00 0x00 

Int64:

0x0031003100310031 == 0x31 0x00 0x31 0x00 0x31 0x00 0x31 0x00

2. Написал. А с ним разве что-то не так?

Re: Строковый вектор инициализации

Теперь все однозначно ясно, еще раз хочу поблагодарить Вас за помощь в решения данной проблемы.

Алексей Перепелов пишет:

2. Написал. А с ним разве что-то не так?

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

Re: Строковый вектор инициализации

Алексей Перепелов пишет:

в Rad-студии и Delphi 7 компилировался один и тот же исходник. Результаты разные.

Не мудрено, ведь в RAD 2010 string уже 2-х байтовый юникод.

(2011-12-09 17:14:20 отредактировано Dmitriy)

Re: Строковый вектор инициализации

Алексей, здравствуйте, старая проблема дала о себе знать вновь.
В предыдущий раз вопрос решился путем преобразования вектора инициализации в Unicode  и использования первых 8-ми байт в GrdCrypt(). Так случилось, что в качестве вектора инициализации были выбраны 4 идентичных символа, как в данном посте так и в некотором количестве случаев в наших проектах. По чистой случайности вчера был сгенерирован вектор, состоящий из 4 различных чисел: 3556. Согласно решению, это значение было преобразовано в Unicode:0x0033003500350036 это значение и передалось в  GrdCrypt() - ожидаемое расшифрованное значение оказалось неверным.
Начал разбираться, нашел закономерность: если все числовые символы вектора инициализации идентичны:"1111"(Unicode:0x0031003100310031),"2222"(Unicode:0x0032003200320032),"3333"(Unicode:0x0033003300330033),........"9999"(Unicode:0x0039003900390039) - расшифрованное значение корректно, в остальных случаях расшифровка возвращает неверный результат, вопрос, почему, как это можно объяснить?

Re: Строковый вектор инициализации

После двухнедельной переписке с тех.поддержкой, особая благодарность Антону Тихиенко, пишу как правильно нужно было конвертировать строку unicode в переменную типа long:

UnicodeEncoding unicode = new UnicodeEncoding();
Byte[] b1 = unicode.GetBytes(sKey);
Int64 InitVectorGS2 = System.BitConverter.ToInt64(b1, 0); 

где sKey - вектор инициализации типа string.