Skip to content

Instantly share code, notes, and snippets.

@volodymyr-korolyov
Last active September 30, 2016 15:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save volodymyr-korolyov/42a0f7b517834c819fddf764a07f24ff to your computer and use it in GitHub Desktop.
Save volodymyr-korolyov/42a0f7b517834c819fddf764a07f24ff to your computer and use it in GitHub Desktop.
-- 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