После прочтения этого поста, у меня возникла идея, а нельзя ли сделать некий текст полностью невидимым? Ниже описанный метод не претендует на эффективность по скорости работы или объёму данных.
Каждый байт строки мы превращаем в трёхзначное восьмеричное число и заменяем каждую цифру на один из невидимых символов.
» Ссылка на GitHub
Разберем по частям этот код.
val v — это массив, содержащий большинство (за исключением U+180E) невидимых Unicode-символов.
def str2oct — функция, превращающая массив байт (например, «hello».getBytes()) в восьмеричное его отображение, например 150 145 154 154 157 (пробелы вставлены для наглядности).
def oct2str — функция, выполняющая обратное преобразование. Разбиваем строку на куски по 3 символа, превращаем триплеты в соответствующий символ и собираем строку обратно.
def voidEnc — замещает восьмеричное число (например, 7) на соответствующий символ из нашего массива невидимых символов.
def voidDec — возвращает число, соответствующее невидимому символу.
def char2void — сначала мы превращаем строку в восьмеричные триплеты (str2oct), а затем каждое число заменяем на невидимый символ (voidEnc)
def void2char — сначала расшифровываем восьмеричные триплеты, а затем превращаем их в строку.
P.S. Не рекомендую публиковать «Войну и мир» или любые другие длинные зашифрованные сообщения в комментариях, потому что это может сломать браузер у многих пользователей.
Вкратце
Каждый байт строки мы превращаем в трёхзначное восьмеричное число и заменяем каждую цифру на один из невидимых символов.
Имплементация на Scala
» Ссылка на GitHub
object Main extends App {
val v = Array("\u2060", "\u200B", "\u2061", "\u2062", "\u2063", "\uFEFF", "\u200C", "\u200D")
def str2oct(buf: Array[Byte]): String = buf.map("%03o" format _).mkString
def oct2str(string: String): String = new String(string.sliding(3,3).toArray.map(x => BigInt(x,8).toByte))
def voidEnc(char: String):String = v(char.toInt)
def voidDec(char:String):String = v.indexOf(char).toString
def char2void(string: String): String = str2oct(string.getBytes()).map(x=>voidEnc(x.toString)).mkString
def void2char(string: String):String = oct2str(string.map(x=>voidDec(x.toString)).mkString)
val void = char2void("Hello! Привет!")
println(void)
val text = void2char(void)
println(text)
}
Разберем по частям этот код.
val v — это массив, содержащий большинство (за исключением U+180E) невидимых Unicode-символов.
def str2oct — функция, превращающая массив байт (например, «hello».getBytes()) в восьмеричное его отображение, например 150 145 154 154 157 (пробелы вставлены для наглядности).
def oct2str — функция, выполняющая обратное преобразование. Разбиваем строку на куски по 3 символа, превращаем триплеты в соответствующий символ и собираем строку обратно.
def voidEnc — замещает восьмеричное число (например, 7) на соответствующий символ из нашего массива невидимых символов.
def voidDec — возвращает число, соответствующее невидимому символу.
def char2void — сначала мы превращаем строку в восьмеричные триплеты (str2oct), а затем каждое число заменяем на невидимый символ (voidEnc)
def void2char — сначала расшифровываем восьмеричные триплеты, а затем превращаем их в строку.
P.S. Не рекомендую публиковать «Войну и мир» или любые другие длинные зашифрованные сообщения в комментариях, потому что это может сломать браузер у многих пользователей.
Поделиться с друзьями
Комментарии (7)
maxru
11.10.2016 11:53Почему именно scala, если не секрет?
a-motion
11.10.2016 12:02+2Предположу, что такие вещи пишутся в том, что на данный момент открыто :)
Unk
11.10.2016 12:05Верно) Ну и реализация на Java была бы менее наглядна и в разы объёмнее
maxru
11.10.2016 15:29+1Ну раз уж это хаб про ненормальное программирование, можно было бы всё в функциональном стиле написать интереса ради :)
Ну и побольше type hinting'ом пользоваться, в конце-то концов, раз уж на скале.
a-motion
Можно `U+180E` использовать как BOM.
Например, менять LTR ?? RTL.
:)
Unk
Думаю, если менять направление текста, то скрытый текст может повлиять на своё окружение и выдать себя
a-motion
Не, я не это имел в виду. Byte Order Marker ровно как в UTF-16.
U+180E
внутри невидимого текста меняет очередность восприятия байт. Впрочем, ладно, это ни о чем было, простите, в общем :)