|
Модераторы: LSD, AntonSaburov |
|
ReFLeXive |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 120 Регистрация: 30.3.2009 Где: г. Уфа Репутация: нет Всего: 1 |
Здраввствуйте!
Задали лабу - реализовать алгоритм шифрования ГОСТ28147. Прочитал ГОСТ, нашел готовую библиотеку (BouncyCastle), просмотрел, понял как и что работает, пересчитал все шаги ручками, чтобы понять как что и куда и начал писать сам. ВСе реализовал! Но вот проблема: в одном из методов класса происходит сложение 2х чисел типа int. Т.к. числа большие, то при сложении происходит переполнение. Однако в готовой библиотеке также стоит сложение 2х чисел типа int! никаких long! Однако у них этот алгоритм наверняка нормально работает. Вот кусок кода (модифицированная версия метода из библиотеки)
PS. Решил было все на long перевести, но столько ошибок повылезало о том, что нельзя привести long к int при битовых операциях сдвига >>, << в строках 6-13. Я даже не знаю теперь, что делать... Это сообщение отредактировал(а) ReFLeXive - 1.3.2011, 23:15 |
|||
|
||||
carper |
|
||||
Бывалый Профиль Группа: Участник Сообщений: 227 Регистрация: 2.3.2005 Репутация: 1 Всего: 8 |
Операции типа << >> для long не запрещены. Вот такой код будет работать:
Если у "них" все нормально работает с int, то не надо "модифицировать" код библиотеки, плохо понимая что делаешь. Дам один практический совет: берете ту самую библиотеку и начинаете маленькими шажками ухудшать код, после каждого шага ОБЯЗАТЕЛЬНО прогоняем тест. Так можно изуродовать текст до такого состояния, что преподаватель сможет сделать вид, что он поверил в то, что код написан самостоятельно. Максимум час и лаба, да еще и с набором тестов, у вас готова. |
||||
|
|||||
math64 |
|
|||
Эксперт Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
А ты учитываешь, что в Java byte и int знаковые?
|
|||
|
||||
ReFLeXive |
|
||||
Шустрый Профиль Группа: Участник Сообщений: 120 Регистрация: 30.3.2009 Где: г. Уфа Репутация: нет Всего: 1 |
Действительно, алгоритм на long я переписал..
ЧТобы понять что там происходит, я потратил не один час времени)) Их библиотеку я не модифицирую - у меня метод просто делает аналогичные операции.
Спасибо за совет! Я лабу делаю не только чтобы сдать ее, так можно вообще не парится и взять у группашей готовую... изобретая этот велосипед, я хочу разобраться как это работает... Поначалу не учитывал, потому и напоролся на переполнение... Хотя, если бы в Java были бы беззнаковые целые - было бы гораздо легче )) |
||||
|
|||||
ReFLeXive |
|
||||||
Шустрый Профиль Группа: Участник Сообщений: 120 Регистрация: 30.3.2009 Где: г. Уфа Репутация: нет Всего: 1 |
Алгоритм я переписал под long, проверил ручками, что должно получится - все сходится, вроде все норм. Проблема вот какая возникла.
Алгоритм отрабатывает, левая и правая части 64 битного блока данных получилась в виде чисел N1 и N2:
В двоичном виде эти числа представлены вот так(использую только младшие 32 бита у типа long):
Далее, я получаю их этих чисел 2 массива по 4 элемента (каждый элемент массива соответствует одному байту в long):
В тип byte элементы массива не влезут, а если использовать int, то потом не получается преобразовать это все в строку.... Как сделать отображение получившихся чисел? |
||||||
|
|||||||
carper |
|
||||
Бывалый Профиль Группа: Участник Сообщений: 227 Регистрация: 2.3.2005 Репутация: 1 Всего: 8 |
Это как это получается, что байт не лезет в байт? Да, на всякий пожарный, N2= {73,78,205,34}, а не 304.
Вы это сейчас вообще о чем? Что int, что byte замечательно отображаются сами по себе, не требуя от вас никаких действий. Нужен какой-то особый формат? Кому вы вообще хотите отображать свой массив? И еще раз, если в исходном классе хватало int, а вам потребовался long, то может повнимательней глянуть на алгоритм? |
||||
|
|||||
ReFLeXive |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 120 Регистрация: 30.3.2009 Где: г. Уфа Репутация: нет Всего: 1 |
тип byte может принимать значения в диапазоне -128 до 127, соответственно символ с кодом 129 в тип byte засунуть не получится в явном виде... Хотя, с другой стороны, знаковая единица в старшем разряде по сути ни на что не влияет с точки зрения битового содержимого числа. Т.е. число 129 в двоичном виде выглядит как 10000001, а для типа byte это битовое представление равно числу -1. Если импользовать >>>, то знак не будет учитываться... Опечатался, извините =) Пример: в результате работы алгоритма получилось число 129. Если использовать тип byte, то вместо 129 будет число -1, а символа с кодом -1 нету... Можно к примеру, это число 129 записать в int, а потом делать явное приведение к char, а из этих char'ов сделать строку... Или даже не засовывать это число в int, a просто использовать >>> при приведении к char. Вобщем, попробую сделать!
В принципе, я теперь понял, что можно обойтись int, используя операцию >>>, чтобы доставать старший байт без учета знаковой единицы... Благо,что использую svn, откатиться несложно... Тут еще другой вопрос возник... Сейчас у меня заточено на тот случай, что каждый символ занимает 1 байт... Соответственно в алгоритме 64битный блок состоит из 8 символов... А ведь если кодировка UTF-8, к примеру, то каждый символ занимает не 1 байт.... как быть в этом случае? Это сообщение отредактировал(а) ReFLeXive - 10.3.2011, 20:43 |
|||
|
||||
ReFLeXive |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 120 Регистрация: 30.3.2009 Где: г. Уфа Репутация: нет Всего: 1 |
Видимо, у меня неверное представление чисел в яве:
Результат будет вот какой: 179 -77 Я думал вот как: число 205 в двоичном виде выглядит 1100 1101; в яве старший байт (самый левый) отвечает за знак, соответственно, если не учитывать эту единицу, то получается число 77 (0100 1101), т.е. получается, в итоге, что число 205 это как бы -77... А тут получается, что -77 соответствует числу 179 без учета знака, которое в двоичном виде выглядит как 1011 0011... Почему так, объясните плиз? Это сообщение отредактировал(а) ReFLeXive - 10.3.2011, 22:06 |
|||
|
||||
jk1 |
|
|||
Эксперт Профиль Группа: Участник Сообщений: 1168 Регистрация: 17.10.2008 Где: Санкт-Петербург Репутация: 40 Всего: 75 |
Потому что установить ведущий бит для смены знака мало. Отрицательные числа представлены так называемым дополнительным кодом: Прямой код. Прямой код двоичного числа совпадает по изображению с записью самого числа. Значение знакового разряда для положительных чисел равно 0, а для отрицательных чисел 1. Обратный код. Обратный код для положительного числа совпадает с прямым кодом. Для отрицательного числа все цифры числа заменяются на противоположные (1 на 0, 0 на 1), а в знаковый разряд заносится единица. Дополнительный код. Дополнительный код положительного числа совпадает с прямым кодом. Для отрицательного числа дополнительный код образуется путем получения обратного кода и добавлением к младшему разряду единицы. В любом представлении старший бит определяет знак числа: 0 - положительное число; 1 - отрицательное число Теперь возвращаемся к примеру. Запишем 77 как 0100 1101. Теперь по алгоритму выше сделаем из него -77, получим 1011 0011. Расширим диапазон: 0000 0000 1011 0011. Теперь этот дополнительный код будет воспринят как прямой из-за того, что знаковый бит не установлен, а для положительных чисел дополнительный код совпадает с прямым. Читаем его как прямой - получаем 179. Это сообщение отредактировал(а) jk1 - 11.3.2011, 04:24 -------------------- Opinions are like assholes — everybody has one |
|||
|
||||
ReFLeXive |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 120 Регистрация: 30.3.2009 Где: г. Уфа Репутация: нет Всего: 1 |
jk1, спасибо вам большое за подробный и исчерпывающий ответ! Алгоритм шифрования у меня в принципе работает, все проверено вручную, вполне нормально считается, вычисляется и т.д. Мне нужно справиться с проблемой представления данных в алгоритме. Т.е. в какой кодировке подавать данные на вход алгоритма? Если к примеру использовать UTF-8, то метод getBytes() для русских символов будет возвращать по 2 байта за каждый символ, если win-1251, то по одному... Соответственно, в первом случае, входной массив данных будет больше и длиннее... Специфика еще такова, что дома я пишу под Linux (кодировка по умолчанию UTF-8), а сдавать лабу буду в универе под windows. Вобщем, подскажите плиз, как правильно и лучше сделать? |
|||
|
||||
Alexandr87 |
|
|||
дыкий псых Профиль Группа: Завсегдатай Сообщений: 1459 Регистрация: 27.11.2004 Где: Алматы, Казахстан Репутация: 9 Всего: 39 |
внимательно алгоритм смотри. там не просто сложение 2х чисел типа int. А сложение по модулю 2^32. |
|||
|
||||
ReFLeXive |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 120 Регистрация: 30.3.2009 Где: г. Уфа Репутация: нет Всего: 1 |
||||
|
||||
ReFLeXive |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 120 Регистрация: 30.3.2009 Где: г. Уфа Репутация: нет Всего: 1 |
Фуух, разобрался, заработало)) Нормально шифрует и расшифровывает!!!
Алгоритм у меня работал верно, косяки были с представлением текстовых данных... Сделал явное указание кодировки windows-1251 и все заработало! Если вдруг кому понадобиться, пишите в лс или на почту (reflexive007_собака_gmail.ru), либо, при желании, могу сюда выложить)) |
|||
|
||||
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |