Как вернуть обработанный список и измененный объект?

Я разрабатываю шифр под названием Дафна, который принимает байт открытого текста и возвращает зашифрованный байт и измененную Дафну. При применении к списку он должен возвращать список зашифрованных байтов и Дафну после обработки всех байтов. Я не уверен, как это сделать, не занимая O (n) памяти. Вот код:

byteEncrypt :: Daphne -> Word8 -> (Daphne,Word8)
byteEncrypt (Daphne key sreg acc) plain = ((Daphne key newsreg newacc),crypt) where
  left = computeLeft key sreg acc
  right = computeRight key sreg acc
  crypt = step plain left right
  newacc = acc+plain
  newsreg = Seq.drop 1 (sreg |> crypt)

byteDecrypt :: Daphne -> Word8 -> (Daphne,Word8)
byteDecrypt (Daphne key sreg acc) crypt = ((Daphne key newsreg newacc),plain) where
  left = computeLeft key sreg acc
  right = computeRight key sreg acc
  plain = invStep crypt left right
  newacc = acc+plain
  newsreg = Seq.drop 1 (sreg |> crypt)

seqEncrypt :: Seq.Seq Word8 -> (Daphne,Seq.Seq Word8) -> (Daphne,Seq.Seq Word8)
seqEncrypt Seq.Empty a = a
seqEncrypt (bs:|>b) (daph,acc) = (daph2,acc2) where
  (daph1,acc1) = seqEncrypt bs (daph,acc)
  (daph2,c) = byteEncrypt daph1 b
  acc2 = acc1 |> c

listEncrypt :: Daphne -> [Word8] -> (Daphne,[Word8])
listEncrypt daph bs = (daph1,toList seq1) where
  (daph1,seq1) = seqEncrypt (Seq.fromList bs) (daph,Seq.Empty)

seqDecrypt :: Seq.Seq Word8 -> (Daphne,Seq.Seq Word8) -> (Daphne,Seq.Seq Word8)
seqDecrypt Seq.Empty a = a
seqDecrypt (bs:|>b) (daph,acc) = (daph2,acc2) where
  (daph1,acc1) = seqDecrypt bs (daph,acc)
  (daph2,c) = byteDecrypt daph1 b
  acc2 = acc1 |> c

listDecrypt :: Daphne -> [Word8] -> (Daphne,[Word8])
listDecrypt daph bs = (daph1,toList seq1) where
  (daph1,seq1) = seqDecrypt (Seq.fromList bs) (daph,Seq.Empty)

listEncrypt имеет копию списка в ОЗУ в виде последовательности, которая занимает O(n) ОЗУ, что не должно быть необходимым.

Полный код находится на https://github.com/phma/daphne. Он еще не готов к производству; Я не проводил криптоанализ, не говоря уже о ком-то еще. Я могу пропускать через него гигабайты данных и вычислять статистику.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не совсем понял, зачем вы вообще ввели последовательности, поэтому я может неправильно понял проблему. Но это похоже на рекурсию список будет работать нормально. Что-то вроде (не проверено)

listEncrypt daph [] = (daph, [])
listEncrypt daph (b:bs) = (finalDaph, e:es)
  where
    (nextDaph, e) = byteEncrypt daph b
    (finalDaph, es) = listEncrypt nextDaph bs

И на самом деле этот паттерн является mapAccumL. Я думаю, что byteEncrypt уже имеет свои аргументы в правильном порядке, так что это будет просто

listEncrypt = mapAccumL byteEncrypt

Любой из них должен нуждаться только в постоянной памяти, но с одной оговоркой. Если вы проверите окончательную дафну перед использованием зашифрованного списка, для например, выполнив print (listEncrypt something something), это будет нужно пройти весь список, чтобы сначала получить окончательную дафну, а хранить весь зашифрованный список в памяти, чтобы иметь возможность использовать этот следующий. Сначала распечатайте зашифрованный список, а затем окончательные daphne и все должно быть в порядке. И если вы только проверяете snd (listEncrypt something something), это должно работать даже в бесконечных списках.

Дафна уже использует последовательность в качестве регистра сдвига, поэтому использование последовательности не добавляет новых библиотек. Скоро пойду по магазинам, вечером попробую.

Pierre Abbat 03.07.2023 19:34

Другие вопросы по теме