삼항 숫자를 순환하여 텍스트를 난독 처리


28

이 과제의 목표는 입력 텍스트를 가져 와서 가장 짧은 함수 / 프로그램을 작성하여 아래 방법을 사용하여 암호화 한 다음 결과를 반환하는 것입니다.

예를 들어 문자열을 사용합니다 hello world.

먼저 입력 텍스트를 가져옵니다.

hello world

둘째 , 문자열을 3 진 (기본 3)으로 변환하십시오. 이 키를 사용하십시오 :

a = 000
b = 001
c = 002
d = 010
e = 011
f = 012
g = 020

...

w = 211
x = 212
y = 220
z = 221
[space] = 222

이 키를 사용하면 아래와 같이 hello world021011102102112222211112122102010됩니다.

 h   e   l   l   o       w   o   r   l   d
021 011 102 102 112 222 211 112 122 102 010

셋째 , 첫 번째 숫자를 끝으로 이동하십시오.

021011102102112222211112122102010
becomes
210111021021122222111121221020100

넷째 , 같은 키를 사용하여 숫자를 다시 문자열로 변환하십시오.

210 111 021 021 122 222 111 121 221 020 100
 v   n   h   h   r       n   q   z   g   j

마지막으로 암호화 된 텍스트를 반환합니다.

vnhhr nqzgj

다음은 몇 가지 샘플 텍스트와 출력입니다.

the turtle ==> dvo fh ego

python ==> uudwqn

code golf ==> hpjoytqgp

이것이 코드 골프이기 때문에 바이트 단위 의 가장 짧은 항목이 이깁니다. 일부 문자가 소문자 나 공백이 아닌 경우 오류가 허용됩니다. 이것이 나의 첫 번째 도전이므로, 어떤 제안이라도 도움이 될 것입니다.

행운을 빕니다!

리더 보드 :

var QUESTION_ID=54643;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),e.has_more?getAnswers():process()}})}function shouldHaveHeading(e){var a=!1,r=e.body_markdown.split("\n");try{a|=/^#/.test(e.body_markdown),a|=["-","="].indexOf(r[1][0])>-1,a&=LANGUAGE_REG.test(e.body_markdown)}catch(n){}return a}function shouldHaveScore(e){var a=!1;try{a|=SIZE_REG.test(e.body_markdown.split("\n")[0])}catch(r){}return a}function getAuthorName(e){return e.owner.display_name}function process(){answers=answers.filter(shouldHaveScore).filter(shouldHaveHeading),answers.sort(function(e,a){var r=+(e.body_markdown.split("\n")[0].match(SIZE_REG)||[1/0])[0],n=+(a.body_markdown.split("\n")[0].match(SIZE_REG)||[1/0])[0];return r-n});var e={},a=1,r=null,n=1;answers.forEach(function(s){var t=s.body_markdown.split("\n")[0],o=jQuery("#answer-template").html(),l=(t.match(NUMBER_REG)[0],(t.match(SIZE_REG)||[0])[0]),c=t.match(LANGUAGE_REG)[1],i=getAuthorName(s);l!=r&&(n=a),r=l,++a,o=o.replace("{{PLACE}}",n+".").replace("{{NAME}}",i).replace("{{LANGUAGE}}",c).replace("{{SIZE}}",l).replace("{{LINK}}",s.share_link),o=jQuery(o),jQuery("#answers").append(o),e[c]=e[c]||{lang:c,user:i,size:l,link:s.share_link}});var s=[];for(var t in e)e.hasOwnProperty(t)&&s.push(e[t]);s.sort(function(e,a){return e.lang>a.lang?1:e.lang<a.lang?-1:0});for(var o=0;o<s.length;++o){var l=jQuery("#language-template").html(),t=s[o];l=l.replace("{{LANGUAGE}}",t.lang).replace("{{NAME}}",t.user).replace("{{SIZE}}",t.size).replace("{{LINK}}",t.link),l=jQuery(l),jQuery("#languages").append(l)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",answers=[],page=1;getAnswers();var SIZE_REG=/\d+(?=[^\d&]*(?:&lt;(?:s&gt;[^&]*&lt;\/s&gt;|[^&]+&gt;)[^\d&]*)*$)/,NUMBER_REG=/\d+/,LANGUAGE_REG=/^#*\s*([^,]+)/;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table></div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table></div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody></table><table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody></table>


3
이것은 기술적으로 암호화가 아닌 난독 화입니다. 여기에는 암호화 키가 없습니다.
John Dvorak

@JanDvorak "암호"가 작동합니까?
거북

@JanDvorak의 의견을 바탕으로 이것을 다른 형식으로 데이터를 표현하는 표준 방법 인 "인코딩"이라고 설명합니다 (예를 들어 16 진 인코딩 또는 base64 인코딩으로 비트 문자열을 표현할 수 있음).
apillers

1
@JanDvorak Agreed- "인코딩"보다는 ROT13을 "난독 화" 라고 부를 가능성이 높습니다 (두 정의를 모두 만족하더라도). 아마 가장 정확한 제목은 "Obfuscate text by ..."일 것입니다.
apsillers

2
@TheTurtle 아이디어는 uint64증가하는 힘을 사용하여 문자를 큰 정수 ( ) 로 묶는 것이 었습니다 27. 한 자릿수의 변위는이 큰 정수에을 곱하는 것과 동일 3하며 다른 쪽 끝의 첫 번째 자릿수의 도입은 단순히 추가입니다. 그러나 마지막 "운반"을 버리는 것 (어쩌면 mod작업을 통해 ) 과 같은 합병증이 있으며 몇 바이트로 작동하지 못했습니다.
Luis Mendo

답변:


16

Pyth, 23 22 바이트

sXc.<sXz=+GdJ^UK3K1KJG

Try it online: Regular Input / Test Suite

Thanks to @isaacg for one byte.

Explanation:

sXc.<sXz=+GdJ^UK3K1KJG
        =+Gd             append a space the G (preinitialized with the alphabet)
               K3        assign 3 to K
            J^UK K       assign all 3-digit ternary numbers 
                         [[0,0,0], [0,0,1],...,[2,2,2]] to J
      Xz  G J            translate input from G to J
     s                   sum (join all ternary numbers to one big list)
   .<             1      rotate by 1
  c                K     split into lists of size 3
 X                  JG   translate from J to G
s                        join chars to string and print

1
We had the same idea. I wrote a Pyth port of my CJam, then scrolled down and saw your answer :/
Andrea Biondo

1
You can save a byte by doing an augmented assignment to G instead of using N, e.g. =+Gd.
isaacg

@isaacg thanks.
Jakube

14

Pyth, 26 bytes

J+Gds@LJiR3c.<s.DR9xLJz1 2

Try it online in the Pyth Compiler/Executor: demo | test cases

Idea

Assume all input characters have already been mapped to the integers that step 2 specifies.

For every 3-digit ternary number, we have that xyz3 = 9x + 3y + z, so modular division by 9 yields quotient x and residue 3y + z.

If the input is abc3 def3 ghi3, applying modular division to each yields a, 3b + c, d, 3e + f, g, 3h + i.

After rotating the list from above one unit to the left, we can group the integers into pairs. This yields the list (3b + c, d), (3e + f, g), (3h + i, a).

Now, if we convert (3y + z, w) from base 3 to integer, we obtain 3(3y + z) + w = 9y + 3z + w = zyw3.

Thus, applying base conversion to the list of pairs gives us bcd3 efg3 hia3, which is precisely the result of rotating the concatenated ternary digits one unit to the left.

All that's left to do is mapping the resulting integers back to characters.

Code

J+Gd                        Concatenate "a...z" (G) with " " (d) and save in J.
                    L z     For each character in the input(z):
                   x J        Compute its index in J.
                 R          For each index I:
               .D 9           Compute (I / 9, I % 9).
              s             Concatenate the resulting pairs.
            .<         1    Rotate the resulting list one unit to the left.
           c             2  Split it back into pairs.
         R                  For each pair:
        i 3                   Perform conversion from base 3 to integer.
      L                     For each resulting integer:
     @ J                      Select the element of J at that index.
    s                       Concatenate the resulting characters.

Yeesh, in a few hours I got beaten by CJam and Pyth. :/
kirbyfan64sos

Wow! Can you write an explanation of how it works? I'm curious. :)
The Turtle

@TheTurtle I've edited my answer.
Dennis

10

Python 2, 96

s=input()
r=y=''
for c in s+s[0]:x=(ord(c)-97)%91;r+=y and chr((y%9*3+x/9-26)%91+32);y=x
print r

Converts a character c to a value x as x=(ord(c)-97)%91, with the modulo affecting only space to convert it to 26. The reverse conversion is i to chr((i-26)%91+32), with the modulo only affecting i=26 to make it become spaces.

We loop through the characters, noting the current value x and the previous value y. We use the last two ternary digits of y, found as y%9, and the first ternary digit of x, found as x/9. The value of the concatenation is y%9*3+x/9. There's probably some optimizations combining this arithmetic with the shifting by 97 and fixing of space.

We make this loop around, we return to the first character of the string at the end. We also do one preparation loop to write in a previous value y, suppressing the character for the first loop when y has not yet been initialized.


8

CJam, 39 29 bytes

The cool thing about this one is that it doesn't even use base conversion.

q'{,97>S+:XZZm*:Yere_(+3/YXer

Try it online.

I just realized I had exactly the same idea as Jakube's Pyth answer. I actually ported this CJam code to Pyth before seeing his post, ending up with 25 bytes. Given it was my first Pyth golf I guess it's not too bad.

Explanation

                              e# Z = 3
q                             e# Push input string
 '{,                          e# Push ['\0' ... 'z']
    97>                       e# Keep ['a' ... 'z']
       S+                     e# Append space
         :X                   e# Assign "a...z " to X
           ZZm*               e# Push 3rd cartesian power of [0 1 2]
                              e# i.e. all 3-digit permutations of 0, 1, 2
                              e# (in lexicographical order)
               :Y             e# Assign those permutations to Y
                 er           e# Translate input from X to Y
                   e_         e# Flatten resulting 2D array
                     (+       e# Rotate first element to the end
                       3/     e# Split back into 3-digit elements
                         YXer e# Translate from Y to X

7

CJam, 30 29 27 bytes

q'{,97>S+:Af#9fmd(+2/3fbAf=

Try it online in the CJam interpreter.

The approach is the same as in my other answer, which is a port of this code to Pyth.

How it works

q                           e# Read from STDIN.
 '{,                        e# Push ['\0' ... 'z'].
    97>                     e# Remove the first 97 elements (['\0' - '`']).
       S+:A                 e# Append a space and save in A.
           f#               e# Find the index of each input character in A.
             9fmd           e# Apply modular division by 9 to each index.
                 (+         e# Shift out the first quotient and append it.
                   2/       e# Split into pairs.
                     3fb    e# Convert each pair from base 3 to integer.
                        Af= e# Select the corresponding elements from A.


6

Javascript (ES6), 175 bytes

A one-liner!

"Overuse of variable v award, anyone?"

update: Now only uses variables called v, for total confusion!

Thanks @vihan for saving 6 bytes!

Thanks @Neil for saving 27 bytes!!

v=>(([...v].map(v=>(v<"V"?53:v.charCodeAt()-70).toString(3).slice(1)).join``)+v[0]).slice(1).match(/..?.?/g).map(v=>(v=String.fromCharCode(parseInt(v,3)+97))>"z"?" ":v).join``

Defines an anonymous function. To use, add v= before the code to give the function a name, and call it like alert(v("hello world"))


You can use .slice(-3) to save 6 bytes, at which point you can use "00"+v to save another byte. (You could concatenate with a template but the resulting length is the same.)
Neil

Actually, you can save a whole bunch of bytes by adding 27 to your values before converting them to base three, as that guarantees enough digits. .map(v=>(v<"V"?26:v.charCodeAt()-97).toString(3)).map(v=>("000"+v).slice(v.length)) then becomes .map(v=>(v<"V"?53:v.charCodeAt()-70).toString(3).slice(1)).
Neil

@Neil Wow, that really shortened the code! It also made it a true 'one-liner', by removing the only intermediate variable. Thanks!
jrich

5

Julia, 149 137 bytes

My first golf!

s->(j=join;b=j([base(3,i==' '?26:i-'a',3)for i=s]);r=b[2:end]*b[1:1];j([i==26?" ":i+'a'for i=[parseint(r[i:i+2],3)for i=1:3:length(r)]]))

(partially) ungolfed:

f = s -> (
    # join the ternary represenations:
    b = join([base(3, i == ' ' ? 26 : i - 'a',3) for i = s]);
    # rotate:
    r = b[2:end] * b[1:1];
    # calculate the new numbers:
    n = [parseint(r[i:i+2],3) for i = 1:3:length(r)];
    # convert back to characters:
    join([i == 26 ? " " : 'a' + i for i = n])
)
assert(f("hello world") == "vnhhr nqzgj")
assert(f("the turtle")  == "dvo fh ego")
assert(f("python")      == "uudwqn")
assert(f("code golf")   == "hpjoytqgp")

You can use = rather than in for loops and you can use b[1] in place of b[1:1]. You also don't need a space between closing parens and for.
Alex A.

@AlexA. Cheers for =, but b[1] returns a character, which can't be appended to a string with *.
kevinsa5

Oh right, forgot about that.
Alex A.

@AlexA. The for trick is nifty. You can also have it directly after a close quote. I didn't realize the parser was that flexible.
kevinsa5

It can also directly follow a numeric literal, as can end.
Alex A.

4

Javascript (ES6), 178, 172, 170

p=>{p=p.replace(' ','{');c="";l=p.length;for(i=0;i<l;){c+=String.fromCharCode(((p.charCodeAt(i)-97)%9)*3+(((p.charCodeAt((++i)%l)-97)/9)|0)+97)}return c.replace('{',' ')}

Replaced Math.floor with a bitwise or. Created an anonymous function. If I'm understanding correctly, this should fix my noobishness somewhat (thanks Dennis!) and get me another 2 bytes down.


3

Julia, 169 166 bytes

s->(J=join;t=J(circshift(split(J([lpad(i<'a'?"222":base(3,int(i)-97),3,0)for i=s]),""),-1));J([c[j:j+2]=="222"?' ':char(parseint(c[j:j+2],3)+97)for j=1:3:length(t)]))

Ungolfed + explanation:

function f(s::String)
    # Convert the input into a string in base 3, with space mapping to 222
    b = join([lpad(i < 'a' ? "222" : base(3, int(i) - 97), 3, 0) for i = s])

    # Split that into a vector of single digits and shift once
    p = circshift(split(b, ""), -1)

    # Join the shifted array back into a string
    t = join(p)

    # Convert groups of 3 back into characters
    c = [t[j:j+2] == "222" ? ' ' : char(parseint(t[j:j+2], 3) + 97) for j = 1:3:length(t)]

    # Return the joined string
    join(c)
end

3

Haskell, 160 bytes

a!k|Just v<-lookup k a=v
x=['a'..'z']++" "
y="012";z=mapM id[y,y,y]
m(a:u:r:i:s)=[u,r,i]:m(a:s)
m[e,a,t]=[[a,t,e]]
main=interact$map(zip z x!).m.(>>=(zip x z!))

Ugh, this feels way too lengthy, but at least I'm... beating Python somehow. And Ruby.


3

Javascript (ES6), 141 124 120 bytes

Believe it or not.... :-)

(t,i=0,c=w=>(t.charCodeAt(w)-123)%91+26)=>String.fromCharCode(...[...t].map(k=>(c(i)%9*3+c(++i%t.length)/9+65|0)%91+32))

As with my other answer, this is an anonymous function, and needs to be assigned to a variable before it can be used. Try it here:

I thought I might be able to shave a couple bytes off my previous answer by using a different technique, so I started out with one similar to Tekgno's and golfed my head off from there. I initialized some variables in the function's argument section, and again stuffed everything into a .map function. Then I realized the String.fromCharCode would be much more efficient outside the .map. After all was said and done, I had shaved off more than 30 45 bytes!

Edit 1: Saved 17 bytes by getting rid of the .replaces, using a technique similar to xnor's Python solution.

OK, maybe it's time to move onto another challenge....


2

Python 2, 182 180 Bytes

This solution is not ideal, due to the replace being very costly.. Trying to figure out how to avoid that.

b=lambda k:k and b(k/3)*10+k%3
s=''.join('%03d'%b(ord(x)-6-91*(x>' '))for x in input())
print`[chr(int((s[1:]+s[0])[i:i+3],3)+97)for i in range(0,len(s),3)]`[2::5].replace('{',' ')

Input is like "hello world".


You need to count 2 bytes for required quotation marks in the input, right?
mbomb007

@mbomb007 That's what I had thought previously, but multiple people have told me I don't need to account for that.
Kade

2

Mathematica, 162 bytes

r=Append[#->IntegerDigits[LetterNumber@#-1,3]~PadLeft~3&/@Alphabet[]," "->{2,2,2}];StringJoin[Partition[RotateLeft[Characters@#/.r//Flatten,1],3]/.(#2->#1&@@@r)]&

(Re)Using a Rule to convert the digit lists to characters and back.


2

Javascript (ES6), 179 bytes

s=>[...s+s[0]].map(q=>`00${(q<'a'?26:q.charCodeAt(0)-97).toString(3)}`.slice(-3)).join``.slice(1,-2).match(/..?.?/g).map(q=>q>221?' ':String.fromCharCode(parseInt(q,3)+97)).join``

Props to vihan for the .match regex.


1

Ruby, 177

Needs at least Ruby 1.9 for the each_char method

l=[*('a'..'z'),' '];n=(0..26).map{|m|m=m.to_s(3).rjust 3,'0'};s='';gets.chomp.each_char{|x|s+=n[l.index x]};puts("#{s[1..-1]}#{s[0]}".scan(/.../).map{|i|i=l[n.index i]}.join '')

1

Java, 458 449 bytes

It made me a little sad to determine that I could shave off 10 bytes by not using Java 8 streams and the map() method.

Here is the golfed version:

import org.apache.commons.lang.ArrayUtils;class A{public static void main(String[]a){int b=0;String[] c=new String[27];for(;b<27;++b)c[b]=String.format("%03d",Integer.valueOf(Integer.toString(b,3)));String d=a[0],e="abcdefghijklmnopqrstuvwxyz ",f="",g="";for(b=0;b<d.length();++b)f+=c[e.indexOf(d.substring(b,b+1))];f=f.substring(1)+f.charAt(0);for(b=0;b<f.length();b+=3)g+=e.charAt(ArrayUtils.indexOf(c,f.substring(b,b+3)));System.out.println(g);}}

Here is a much less golfed version. It is intended to be readable, but I make no guarantees.

import org.apache.commons.lang.ArrayUtils;
class A {
    public static void main(String[] a) {
        int b=0;
        String[] c = new String[27];
        for (; b < 27; ++b)
            c[b] = String.format("%03d", Integer.valueOf(Integer.toString(b, 3)));
        String
            d = a[0],
            e = "abcdefghijklmnopqrstuvwxyz ",
            f = "",
            g = "";
        for (b = 0; b < d.length(); ++b)
            f += c[e.indexOf(d.substring(b, b + 1))];
        f = f.substring(1) + f.charAt(0);
        for (b = 0; b < f.length(); b += 3)
            g += e.charAt(ArrayUtils.indexOf(c, f.substring(b, b + 3)));
        System.out.println(g);
    }
}

This program takes the string to convert as a command-line argument. If you want to have spaces in your input, you have to surround it with double quotes.

I wanted to provide an example of using this from the command line, but I was unable to get this code to work outside of Eclipse. I never learned to use Java from the command line ^_^; You can probably get this running inside the IDE of your choice without too much trouble.


if you only use the ArrayUtils once using the fully qualified name inside the code is shorter than that import statement. see: codegolf.stackexchange.com/a/16100/10801 (bottom half of linked answer)
masterX244

1

Javascript (ES6), 181 180 bytes

t=>((x=[...t].map(k=>`00${(k<'!'?26:k.charCodeAt(0)-97).toString(3)}`.slice(-3)).join``).slice(1)+x[0]).match(/.../g).map(j=>j>221?' ':String.fromCharCode(parseInt(j,3)+97)).join``

This is an anonymous function, so it needs to be given a name before it can be used. (E.g. encrypt=t=>...) Try it out here:

I started out using multiple variables and for loops instead of .map. I then golfed it in every possible way without changing the algorithm, which put me somewhere around 217 bytes. After taking a look at UndefinedFunction's answer, I managed to get it down to 195, and some inspection of Dendrobium's answer resulted in another 14 golfed off.

As far as I'm aware, I can't go any further or my result would be practically identical to Dendrobium's (except for being one character shorter!). Can anyone find the place where I saved one char? :-)

As usual, suggestions are gladly welcome!


Thanks for the regex tip! I'm not sure how exactly the for-of loop could be worked into this one-line function, but perhaps it would save some space anyway. You can post your version if you like.
ETHproductions

0

Matlab, 113 bytes

x=dec2base(strrep(input('','s'),' ','{')-97,3)';strrep(char(base2dec(reshape(x([2:end 1]),3,[])',3)+97)','{',' ')

Input is through stdin.

Example:

>> x=dec2base(strrep(input('','s'),' ','{')-97,3)';strrep(char(base2dec(reshape(x([2:end 1]),3,[])',3)+97)','{',' ')
hello world
ans =
vnhhr nqzgj

0

Julia - 92 87 61 54 bytes

s->join(32+(3(i=[s...]%91+579)%27+i[[2:end,1]]÷9)%91)

Ungolfed:

function f(s)
  t=[s...];       # Convert the string into a char array
                      #
  i=t%91+579          # Mod 91 drops the alpha characters to sit just
                      # below space, then 579 is added as a trick,
                      # equivalent to subtracting 6 and adding 9*65
  v1=3i%27            # This shifts the bottom two ternary digits up
                      # and removes the first ternary digit
  v2=i[[2:end,19    # This shifts the first ternary digit down and
                      # removes the bottom two ternary digits. [2:end,1]
                      # rotates the array to put the first value at the end
  N=(v1+v2)%91+32     # this combines the ternary digits, then returns
                      # the values to the correct ASCII values
  j=join(N)           # join the char array back to a string
  return j
end

The trick may confuse you. Subtracting 6 moves 'a' down to zero after the mod. Adding 9*65 is equivalent to adding 65 to v1+v2, which is part of the process of restoring the values to their ascii values. You could replace i=t%91+579 with i=t%91-6, and then replace N=(v1+v2)%91+32 with N=(v1+v2+65)%91+32 to get the same result, but it requires one extra character.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.