Строки в Java являются Unicode - и строки Unicode не являются общими держателями для байтов, как могут быть строки ASCII.
Вы берете строку и конвертируете ее в байты, не указывая, какую кодировку символов вы хотите, поэтому вы получаете кодировку по умолчанию для платформы - вероятно, US-ASCII, UTF-8 или одну из кодовых страниц Windows.
Затем вы выполняете арифметические / логические операции над этими байтами. (Я не смотрел на то, что вы здесь делаете - вы говорите, что знаете алгоритм.)
Наконец, вы берете эти преобразованные байты и пытаетесь превратить их обратно в строку, то есть обратно в символы. Опять же, вы не указали кодировку символов (но вы получите то же самое, что и преобразование символов в байты, так что все в порядке), но, самое главное ...
Если в кодировке вашей платформы по умолчанию используется один байт на символ (например, US-ASCII), то не все сгенерированные вами последовательности байтов представляют действительные символы.
Итак, из этого следует два совета:
- Не использовать строки в качестве общих держателей для байтов
- Всегда указывайте кодировку символов при преобразовании между байтами и символами.
В этом случае вы могли бы добиться большего успеха, если бы вы специально указали кодировку US-ASCII. РЕДАКТИРОВАТЬ: Это последнее предложение не соответствует действительности (см. Комментарии ниже). Вернитесь к пункту 1 выше! Используйте байты, а не символы, если вам нужны байты.