Реестр и логические операции над строками
Приспичило мне тут "типа зашифровать" строку в реестре. Ну вот захотелось и все, трава не расти! Причем запись и чтение надо выполнять и из-под лиспа, и из-под NET. И вот тут я знатно удивился...
Имя ветки реестра известно (пусть будет HKCU\SOFTWARE\kpblcTest), ключ - SomeData, записываемая строка в исходном виде - "Проверка работы".
На лиспе все очень просто и элементарно - через аналог XOR прогоняем посимвольно и не паримся по поводу:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | (defun write-reg (hive key data) (vl-registry-write hive key (vl-list->string (mapcar (function (lambda (x) (boole 6 x 128) ) ) (vl-string->list data) ) ) ) ) (defun read-reg (hive key) (vl-list->string (mapcar (function (lambda (x) (boole 6 x 128) ) ) (vl-string->list (vl-registry-read hive key)) ) ) |
Код элементарен и пояснений, надеюсь, не требует.
Но потом мне надо в NET прочитать и "расшифровать" эти данные. Ну вот надо, и все тут.
"И в чем проблема?" - подумал я:
1 2 3 4 5 6 | RegistryKey curUserKey = Registry.CurrentUser; RegistryKey parentKey = curUserKey.OpenSubKey("SOFTWARE\\kpblcTest"); string value = parentKey.GetValue("SomeData").ToString(); return new string(value.Select(o => (char)((byte)o ^ 128)).ToArray()); |
Ага, щщас! На выходе получаю вообще полнейшую белиберду!
Два часа и десяток сигарет спустя до меня доходит: возможно, проблема всего лишь в кодировке. Что-то там такое где-то мелькало... Ну ок, попробую принудительно указать кодировку (да, мне надо только читать; да, lisp работает только с Win-1251 кодировкой в наших реалиях; да, при попытке записи в реестр через NET и последующим чтением через lisp я наверняка столкнусь с аналогичными проблемами, я знаю):
1 2 3 4 5 6 7 8 9 10 11 | RegistryKey curUserKey = Registry.CurrentUser; RegistryKey parentKey = curUserKey.OpenSubKey("SOFTWARE\\kpblcTest"); string value = parentKey.GetValue("SomeData").ToString(); Encoding sourceEncoding = Encoding.GetEncoding("windows-1251"); byte[] sourceBytes = sourceEncoding.GetBytes(value); return new string(sourceBytes.Select(item => (char)((byte)item ^ 128)) .ToArray() ); |
И вот тут как раз я и получаю чего хотел. Дополнительные проверки типа "а существует ли ключ", "а есть ли там данные" и прочая, и прочая - оставляю за скобками.
Вот уж не ожидал, что запись / чтение реестра может быть сопряжено с вопросами кодировки...