Last active
September 30, 2016 15:40
-
-
Save volodymyr-korolyov/42a0f7b517834c819fddf764a07f24ff to your computer and use it in GitHub Desktop.
SQL solution to http://www.meetup.com/functional-kats-cork/events/234061670/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Tested on Postgres 9.2 | |
create or replace temp view cipher as | |
select | |
'meetmebythetree'::varchar plain_text, | |
'scones'::varchar secret; | |
with | |
-- Recursively add 'secret' until result is longer than 'plain_text' | |
recursive secret_stream(repeated_secret) as ( | |
select ''::varchar | |
union all | |
select repeated_secret || (select secret from cipher) | |
from secret_stream | |
where length(repeated_secret) < (select max(length(plain_text)) from cipher) | |
), | |
-- Transform to field-value table | |
denormalized_cipher as ( | |
select 'plain_text' field, plain_text field_value from cipher | |
union | |
select 'secret', max(repeated_secret) from secret_stream | |
), | |
-- For each character in text or secret, create row with its index and value. Example: | |
-- 'plain_text', 1, 'm' | |
-- 'plain_text', 2, 'e' | |
split_cipher as ( | |
select field, row_number() OVER(partition by field) c_order, c | |
from ( | |
select field, unnest(string_to_array(field_value, NULL)) c | |
from denormalized_cipher | |
) t | |
), | |
-- Zip plain text and secret together | |
zip as ( | |
select plain_text.c plain_char, secret.c secret_char | |
from split_cipher plain_text | |
inner join split_cipher secret on secret.c_order = plain_text.c_order | |
where plain_text.field = 'plain_text' and secret.field = 'secret' | |
), | |
-- Encode each character | |
encode as ( | |
select chr(ascii('a') + (ascii(plain_char) - ascii('a') + ascii(secret_char) - ascii('a')) % 26) encoded_char | |
from zip | |
), | |
-- Merge result back into string | |
mkstr as ( | |
select string_agg(encoded_char, '') from encode | |
) | |
SELECT * | |
FROM mkstr; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment