ROT คืออะไร - ถอดรหัส ROT-n


25

นี่คือตัวอักษรของตัวอักษรภาษาอังกฤษตามลำดับความถี่:

e t a o i n s h r d l c u m w f g y p b v k j x q z

นั่นคือeเป็นจดหมายที่ใช้บ่อยที่สุดและzเป็นจดหมายที่พบน้อยที่สุด (ข้อมูลจากWikipedia )

ความท้าทายของคุณคือการใช้ข้อความ ROT-n'd เช่น:

ocdndnvqzmtnzxmzohznnvbzocvodnqzmtnzxpmzviynvaz

นี่คือข้อความ "นี่คือทุกสิ่งที่ส่งมาถึงความพึงพอใจของคุณปลอดภัย" ซึ่ง "เข้ารหัส" ผ่าน ROT-21 (ครึ่งหนึ่งของ 42) โปรแกรมของคุณที่ใช้ตารางความถี่ด้านบนควรสามารถกำหนดได้ว่าอักขระแต่ละตัวถูกหมุนและข้อความต้นฉบับเท่าใด

(หากคุณไม่คุ้นเคยกับ ROT-n มันจะเปลี่ยนอักขระแต่ละตัวเป็นหลักnเช่นใน ROT-2,. a -> c, b -> d, ..., x -> z, y -> a, z -> b)

คุณถามอย่างไร อัลกอริทึม (ไร้เดียงสามาก) ที่คุณต้องใช้คือ:

  • สำหรับแต่ละnตั้งแต่0ถึง25รวมให้ใช้ ROT- -nกับสตริงอินพุต (เป็นลบnเพราะเราต้องการย้อนกลับการเข้ารหัส ROT- -nเทียบเท่ากับ ROT- 26-nถ้าทำได้ง่ายกว่านี้)
  • แปลงแต่ละอินพุตสตริงเป็นตัวเลขโดยการเพิ่มความถี่สัมพัทธ์ของอักขระ eis 0, tis 1, ais 2, etc. ตัวอย่างเช่นจำนวนที่สอดคล้องกันของสตริง"hello"คือ 7 + 0 + 10 + 10 + 3 = 30
  • ค้นหาสตริงที่มีตัวเลขที่ต่ำที่สุด
  • nผลลัพธ์ที่สตริงและสอดคล้องกัน

กฎ:

  • อินพุตสามารถทำได้ทุกที่ที่เหมาะสม (STDIN, อาร์กิวเมนต์ของฟังก์ชั่น, จากไฟล์, ฯลฯ ) และสามารถส่งออกได้ (STDOUT, ค่าส่งคืนของฟังก์ชัน, ไปยังไฟล์, ฯลฯ )
  • คุณอาจใช้อัลกอริทึมที่แตกต่างกันตราบใดที่มันให้ผลลัพธ์ที่เหมือนกันเสมอ ตัวอย่างเช่นการมีค่าzเป็น 0 และe25 และการเลือกจำนวนสูงสุดก็ไม่เป็นไร
  • หากสองสายมีคะแนนเท่ากันคุณสามารถเลือกที่จะแสดงผลออกมาหนึ่งหรือทั้งสอง นี่เป็นกรณีที่เป็นขอบและคุณไม่จำเป็นต้องคิดค่าใช้จ่าย
  • นี่คือดังนั้นโค้ดที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ!

กรณีทดสอบ:

อินพุต: ocdndnvqzmtnzxmzohznnvbzocvodnqzmtnzxpmzviynvaz
เอาต์พุต:21 thisisaverysecretmessagethatisverysecureandsafe

อินพุต: pmttwxmwxtmwnxzwoziuuqvoxchhtmakwlmowtnabiksmfkpivom
เอาต์พุต:8 hellopeopleofprogrammingpuzzlescodegolfstackexchange

อินพุต: ftueimeqzodkbfqpiuftdaffiqxhqeaufygefnqbqdrqofxkemrq
เอาต์พุต:12 thiswasencryptedwithrottwelvesoitmustbeperfectlysafe

อินพุต: jgtgkuvjghkpcnvguvecugvjcvaqwowuvfgetarv
เอาต์พุต:2 hereisthefinaltestcasethatyoumustdecrypt

ในกรณีที่คุณสงสัยนี่คือ JSFiddle ของรหัสทดสอบ JavaScript ที่ฉันเขียนซึ่งประสบความสำเร็จในการถอดรหัสกรณีทดสอบทั้งหมดที่ฉันโยนไป


มันอาจมีประโยชน์ในการจดบันทึกกรณีขอบ ตัวอย่างเช่นwtaadควรให้0 wtaadผลลัพธ์และvszzcควรให้25 wtaadผลลัพธ์
mellamokb

คุณควรให้คะแนนพิเศษสำหรับการตรวจจับการใช้งาน TrippleROT-N
user19713

@ user19713 triplerot คืออะไร ฉันหมายถึงอะไรคือความแตกต่างระหว่าง ROT-6 และสามเท่า ROT-2
Mr Lister

2
@mrlister มันเป็นเรื่องตลกเก่าแก่ที่เอาปัสสาวะออกจาก TripleDES
user19713

เราสามารถส่งออก n-root หลังจากสตริงถอดรหัสหรือไม่
นายกเทศมนตรีราย

คำตอบ:


6

GolfScript - 87

สูตรโกงที่นี่คือการสร้างทุกการหมุนพร้อมกัน เนื่องจากเราจำเป็นต้องวนซ้ำทุก ROT จากนั้นตัวละครทุกตัวเราแค่วนซ้ำตัวอักษรทุกตัวแล้วฝานตัวอักษรทั้งหมดแล้วซิปขึ้น จากนั้นดำเนินการตามที่คาดไว้: นับคะแนนสำหรับแต่ละ ROT และเลือกขั้นต่ำ

เสริมกอล์ฟ:

{97- 26,{97+}%.+''+>}/]{27<}%zip:d{{"etaoinshrdlcumwfgypbvkjxqz"?}%{+}*}%.$0=?.26\-\d=

เพียงกอล์ฟนิดหน่อย:

# the alphabet, and by frequency
26,{97+}%.+''+:a;
"etaoinshrdlcumwfgypbvkjxqz":f;

# build evey ROT decryption
{97-a>}/]{27<}%zip:d

# calculate likelihood
{{f?}%{+}*}%.

# find min
$0=

# output rotation factor and decryption
?.26\-\d=

8

Haskell - 192 175

f y=sum.map(\x->length.fst$break(==x)y)
main=interact(\s->snd$minimum$[(f"etaoinshrdlcumwfgypbvkjxqz"r,show(26-n)++" "++r)|n<-[0..25],let r=map(\x->([x..'z']++['a'..])!!n)s])

วิ่ง

% ./rot-n <<< "pmttwxmwxtmwnxzwoziuuqvoxchhtmakwlmowtnabiksmfkpivom"
8 hellopeopleofprogrammingpuzzlescodegolfstackexchange

แทนที่จะรวมความยาวคุณสามารถสร้างรายการที่แสดงตัวเลขเป็นตัวเลขเช่น[1,1,1,1]และสิ่งนี้จะให้ลำดับเดียวกัน การทำแผนที่และการรวมนั้นจะกลายเป็นconcatMapซึ่งสามารถเขียนรัดกุมโดยใช้รายการความเข้าใจ บวกกับเทคนิคอื่น ๆ ไม่กี่ผมสั้นลงไปที่ 152 main=interact(\s->snd$minimum[([1|x<-r,_<-fst$span(/=x)"etaoinshrdlcumwfgypbvkjxqz"],show(26-n)++' ':r)|n<-[0..25],r<-[[([x..'z']++['a'..])!!n|x<-s]]])ตัวอักษร:
hammar

7

GolfScript, 112 108 102 100 ตัวอักษร

{{}/]{97-}%}:b~:|;"etaoinshrdlcumwfgypbvkjxqz"b:f,:&,{:x[|{&x-+&%f?}%{+}*\]}%$0=1=:x|{&x-+&%97+}%''+

ฉันไม่มีความสุขกับการทำซ้ำด้วยการถอดรหัสซ้ำในตอนท้าย

Ungolfed (หากมีเหตุผล: P) และรุ่นที่เก่ากว่าเล็กน้อย:

# store input IDs (a = 0, b = 1, etc.) in s
[{}/]{97-}%:s;
# store frequency data IDs in f (blah, repetition)
"etaoinshrdlcumwfgypbvkjxqz"[{}/]{97-}%:f

# for each number from 0 to 26 (length of previous string left unpopped)...
,,{
  # the number is x
  :x;
  # return an array of...
  [
    # the score
    s{x 26\-+26%f?}%{+}*
    # and the n
    x
  ]
}%

# use $ort to find the n to output
$0=1=:x

# get the string that the n corresponded to (blah, more repetition)
s{x 26\-+26%97+}%''+

"การป้อนข้อมูลสามารถทำได้ทุกที่ที่เหมาะสม" จะช่วย GolfScript ในตอนแรกฉันไม่สามารถเข้าใจได้ว่าทำไมสคริปต์ของเราทั้งคู่ดูเหมือนจะพิมพ์ตัวละครพิเศษในตอนท้ายจนกว่าฉันechoจะรู้ว่าจะมีการขึ้นบรรทัดใหม่ตามค่าเริ่มต้นซึ่งล่ามจะมารับ
couchand

6

จาวาสคริปต์ (205)

f='zqxjkvbpygfwmucldrhsnioate';a='abcdefghijklmnopqrstuvwxyz';for(s=prompt(o=m=n=0)
,i=27;i--;w>m&&(m=w,n=i,o=u))for(u='',w=c=0;c<s.length;w+=f.indexOf(x))u+=x=(a+a)[a
.indexOf(s[c++])+i];alert((26-n)+' '+o)

ฉันคิดว่ามันยังสามารถตีกอล์ฟได้มากกว่านี้ดังนั้นยินดีให้คำแนะนำ!

หมายเหตุบางประการเพื่อช่วยให้เข้าใจวิธีแก้ปัญหา

  • m, nและoติดตามคะแนนสูงสุด
  • u และ wติดตามผลลัพธ์ของตัวละครและค่าตามลำดับสำหรับปัจจุบันi
  • (a+a) ช่วยป้องกันการไหลล้นเมื่อพันรอบที่ผ่านมา zและสั้นกว่าการทำ%26
  • ฉันมีความถี่ในลำดับย้อนกลับเพื่อให้ฉันสามารถค้นหาสูงสุดแทนนาที

หลักฐาน: http://jsfiddle.net/J9ZyV/5/



4

C # + Linq - 273 264

ในฐานะที่เป็นฟังก์ชั่นที่รับสตริงป้อนเข้าและส่งคืนสตริงถอดรหัส & ชดเชย (ตามข้อกำหนด):

static Tuple<string,int> d(string s){var r=Enumerable.Range(0,25).Select(i=>string.Concat(from c in s select (char)((c-97+i)%26+97))).OrderBy(x=>(from c in x select "etaoinshrdlcumwfgypbvkjxqz".IndexOf(c)).Sum()).First();return Tuple.Create(r,(s[0]-r[0]+26)%26);}

ไม่พอใจกับความคิดเห็น:

static Tuple<string,int> d(string s)
{
    var r=Enumerable.Range(0,25)                                               // for every possible offset i
          .Select(i=>string.Concat(from c in s select (char)((c-97+i)%26+97))) // calculate rot_i(input string)
          .OrderBy(                                                            // order these by their score
              x=>(
              from c in x select "etaoinshrdlcumwfgypbvkjxqz".IndexOf(c)       // lookup frequency of each character
              ).Sum()                                                          // and sum each frequency to get the score
           ).First();                                                          // get the first one (lowest score)

    return Tuple.Create(r,(s[0]-r[0]+26)%26);                                  // compute offset and return results
}

โปรแกรมควบคุมการทดสอบเล็กน้อย (อย่าลืมรวบรวมการอ้างอิงSystem.Coreสำหรับ Linq):

using System;
using System.Linq;

namespace codegolf
{
    class Program
    {
        static Tuple<string,int> d(string s){var r=Enumerable.Range(0,25).Select(i=>string.Concat(from c in s select (char)((c-97+i)%26+97))).OrderBy(x=>(from c in x select "etaoinshrdlcumwfgypbvkjxqz".IndexOf(c)).Sum()).First();return Tuple.Create(r,(s[0]-r[0]+26)%26);}

        static void Main(string[] args)
        {
            while (true)
            {
                var input = Console.ReadLine();
                if (input == null) break;
                var retval = d(input);
                Console.WriteLine(String.Format("{0} {1}", retval.Item2, retval.Item1));
            }
        }
    }
}

ให้:

$ mcs /reference:System.Core.dll main.cs && mono ./main.exe
ocdndnvqzmtnzxmzohznnvbzocvodnqzmtnzxpmzviynvaz
21 thisisaverysecretmessagethatisverysecureandsafe
pmttwxmwxtmwnxzwoziuuqvoxchhtmakwlmowtnabiksmfkpivom
8 hellopeopleofprogrammingpuzzlescodegolfstackexchange
ftueimeqzodkbfqpiuftdaffiqxhqeaufygefnqbqdrqofxkemrq
12 thiswasencryptedwithrottwelvesoitmustbeperfectlysafe
jgtgkuvjghkpcnvguvecugvjcvaqwowuvfgetarv
2 hereisthefinaltestcasethatyoumustdecrypt
thisisaverysecretmessagethatisverysecureandsafe
0 thisisaverysecretmessagethatisverysecureandsafe

ฉันคิดว่าคุณผิดพลาด - โซลูชันปัจจุบันของคุณคือ 263 ตัวอักษร นอกจากนี้คุณสามารถประหยัดถ่านอีกหนึ่งTuple<string,int> d
ก้อน

นี่คือเวอร์ชันของฉันซึ่งใกล้เคียงกับการนำไปใช้ แต่สั้นกว่าเล็กน้อย:Tuple<int,string>f(string x){return Enumerable.Range(0,25).Select(n=>Tuple.Create(26-n,string.Concat(x.Select(c=>(char)((c-97+n)%26+97))))).OrderBy(t=>(t.Item2.Select(c=>"etaoinshrdlcumwfgypbvkjxqz".IndexOf(c))).Sum()).First();}
porges

ฉันคิดว่าคุณควรจะใช้ไม่ได้Range(0, 26) 25
Rawling

4

dg - 137 130 129 128 ไบต์

f=t->min key:(t->sum$map 'etaoinshrdlcumwfgypbvkjxqz'.index$snd t)$map(n->n,''.join$map(c->chr$((ord c + 7-n)%26+ 97))t)(0..26)

ตัวอย่าง:

>>> f 'ocdndnvqzmtnzxmzohznnvbzocvodnqzmtnzxpmzviynvaz'
(21, 'thisisaverysecretmessagethatisverysecureandsafe')
>>> f 'pmttwxmwxtmwnxzwoziuuqvoxchhtmakwlmowtnabiksmfkpivom'
(8, 'hellopeopleofprogrammingpuzzlescodegolfstackexchange')
>>> f 'ftueimeqzodkbfqpiuftdaffiqxhqeaufygefnqbqdrqofxkemrq'
(12, 'thiswasencryptedwithrottwelvesoitmustbeperfectlysafe')
>>> f 'jgtgkuvjghkpcnvguvecugvjcvaqwowuvfgetarv'
(2, 'hereisthefinaltestcasethatyoumustdecrypt')

รหัสไม่ได้รับการตอบกลับ:

func = t ->
  #: Compute the score of the text `t` with respect to the frequency table.
  #: score :: (int, str) -> int
  score = t ->
    sum $ map 'etaoinshrdlcumwfgypbvkjxqz'.index $ snd t

  #: Compute rot-n of the string `t`. Return the offset and the shifted text.
  #: rot :: int -> (int, str)
  rot = n ->
    n, ''.join $ map (c->chr $ ((ord c + 7 - n) % 26 + 97)) t

  # return the minimum (computed by `score`) amongst all shifted messages
  min key: score $ map rot (0..26)

คุณไม่สามารถลบช่องว่างที่คนรอบข้างc - 97และ(0..26)?
mniip

ฉันสามารถลบอันที่สองเท่านั้น ทำมันตอนนี้ ฉันจะเพิ่มตัวอย่างบางส่วนเช่นกัน
บิค

1
ไม่เคยได้ยินมาdgก่อน คุณสามารถให้ลิงค์หรือไม่
TheDoctor

@TheDoctor: แน่นอน! pyos.github.io/dgเป็นหน้าแรกและpyos.github.com/dg/tutorialการสอน
rubik

คุณสามารถบันทึกหนึ่งตัวละครโดยการเพิ่ม 7 แทนการลบ 97 Modulo 26 พวกเขาเป็นสิ่งเดียวกัน
hammar

4

J - 92 ตัวอักษร

บิตของลูกเป็ดขี้เหร่ แต่มันใช้ได้ ส่งออกจำนวนและจากนั้นสตริงในสองบรรทัด

(26|](-1!:2&2&.":)(/:'ctljapqhewvknfdsyigbmuoxrz')+/@i."1(i.<./@:)26|(i.-27)+/])&.(_97+3&u:)

หากคุณต้องการให้พวกเขาอยู่ในบรรทัดเดียวกันช่องว่างคั่นสิ่งนี้จะขึ้นอยู่กับ93 ถ่านแต่ใช้เส้นทางที่น่าเกลียด

((":@],[:u:32,97+26|-)(/:'ctljapqhewvknfdsyigbmuoxrz')+/@i."1(i.<./@:)26|(i.-27)+/])@(7+3&u:)

คำอธิบายสำหรับ (/:'ctljapqhewvknfdsyigbmuoxrz') : ในคำกริยานี้เราดำเนินการกับค่าตัวอักษรเป็น A = 0, B = 1, C = 2, ฯลฯ ในการเข้ารหัสค่าตัวอักษรของสตริงetaoinshrdlcumwfgypbvkjxqzวิธีที่สั้นที่สุดคือการเรียงสับเปลี่ยนเรียงลำดับสำหรับสิ่งนี้ สตริงแปลก นี่เป็นเพราะ A อยู่ที่ดัชนี 4, B ที่ดัชนี 19, C ที่ 0, D ที่ 14, และอื่น ๆ ; ดังนั้นการเรียงลำดับการเรียงลำดับคือ4 19 0 14 8 13 ...เมื่อคุณให้คะแนน ( /:) มันและคุณจะได้รับค่าตัวเลขอย่างแน่นอนetaoin...อย่างแน่นอน

การใช้งาน:

   (26|](-1!:2&2&.":)(/:'ctljapqhewvknfdsyigbmuoxrz')+/@i."1(i.<./@:)26|(i.-27)+/])&.(_97+3&u:) 'ocdndnvqzmtnzxmzohznnvbzocvodnqzmtnzxpmzviynvaz'
21
thisisaverysecretmessagethatisverysecureandsafe

   NB. naming for convenience
   f =: (26|](-1!:2&2&.":)(/:'ctljapqhewvknfdsyigbmuoxrz')+/@i."1(i.<./@:)26|(i.-27)+/])&.(_97+3&u:)
   f 'pmttwxmwxtmwnxzwoziuuqvoxchhtmakwlmowtnabiksmfkpivom'
8
hellopeopleofprogrammingpuzzlescodegolfstackexchange
   f 'wtaad'
0
wtaad

3

q, 97

{(w;m w:g?min g:(+/')("etaoinshrdlcumwfgypbvkjxqz"!t)m:(t!u!/:rotate[;u:.Q.a]'[(-)t:(!)26])@\:x)}

.

q) tests:(
    "ocdndnvqzmtnzxmzohznnvbzocvodnqzmtnzxpmzviynvazocdndnvqzmtnzxmzohznnvbzocvodnqzmtnzxpmzviynvaz";
    "pmttwxmwxtmwnxzwoziuuqvoxchhtmakwlmowtnabiksmfkpivom";
    "ftueimeqzodkbfqpiuftdaffiqxhqeaufygefnqbqdrqofxkemrq";
    "jgtgkuvjghkpcnvguvecugvjcvaqwowuvfgetarv")

q) f:{(w;m w:g?min g:(+/')("etaoinshrdlcumwfgypbvkjxqz"!t)m:(t!u!/:rotate[;u:.Q.a]'[(-)t:(!)26])@\:x)}

q) f each tests
21 "thisisaverysecretmessagethatisverysecureandsafethisisaverysecretmessagethatisverysecureandsafe"
8  "hellopeopleofprogrammingpuzzlescodegolfstackexchange"
12 "thiswasencryptedwithrottwelvesoitmustbeperfectlysafe"
2  "hereisthefinaltestcasethatyoumustdecrypt"

2

APL - 70 ตัวอักษร

F←{↑⍋+/'etaoinshrdlcumwfgypbvkjxqz'⍳⊃(⍳26){l[(⍺⌽l←⎕UCS 97+⍳26)⍳⍵]}¨⊂⍵}

ตัวอย่าง:

      F 'ocdndnvqzmtnzxmzohznnvbzocvodnqzmtnzxpmzviynvaz'
21
      F 'pmttwxmwxtmwnxzwoziuuqvoxchhtmakwlmowtnabiksmfkpivom'
8
      F 'ftueimeqzodkbfqpiuftdaffiqxhqeaufygefnqbqdrqofxkemrq'
12
      F 'jgtgkuvjghkpcnvguvecugvjcvaqwowuvfgetarv'
2

ฉันแน่ใจว่ามีวิธีบีบอัดข้อมูลนี้เพิ่มเติมและฉันเชิญผู้ใช้ APL รายอื่น ๆ มาหาวิธีแก้ไขปัญหาดังกล่าว


6
คุณมีการส่งออกสตริงตัดสินใจเกินไป ...
Doorknob

2

Python 188

x="abcdefghijklmnopqrstuvwxyz"
y=input()
r=lambda n:"".join(x[x.find(i)-n]for i in y)
s={sum("etaoinshrdlcumwfgypbvkjxqz".find(b)for b in r(a)):(a,r(a))for a in range(26)}
print(s[min(s)])

1

Perl: 256 อักขระ (รวมถึงบรรทัดใหม่สำหรับการอ่าน) รวมถึงตารางความถี่:

@f=unpack("W*","etaoinshrdlcumwfgypbvkjxqz");
@c=unpack("W*",<>);$m=ord("a");$b=1E10;
for$n(0..25){$s=0;$t="";
for$x(0..scalar@c){$r=($c[$x]-$n-$m)%26+$m;$t.=chr($r);
for(0..scalar@f){if($r==$f[$_]){$s+=$_}}}
if($s<$b){$b=$s;$w=$t;$a=$n}}
printf"%d %s\n",$a,$w;

ข้อความมีให้เช่น:

echo "ocdndnvqzmtnzxmzohznnvbzocvodnqzmtnzxpmzviynvaz" | perl ./freq.pl 
21 thisisaverysecretmessagethatisverysecureandsafewm

ถอด 12 ถ่านถ้าคุณต้องการที่จะอบในค่าของ ord (a) และความยาวของ @f


1

เอล์ม - 465

จะไม่ชนะรางวัลการเล่นกอล์ฟ แต่จะสร้างเว็บเพจแบบคงที่ซึ่งแสดงรายการของแบบฟอร์ม[(rotation number, rotated string)]ในขณะที่คุณพิมพ์

หมายเหตุ: ยังไม่ทำงานที่นี่แต่คุณสามารถคัดลอกวางลงในตัวแก้ไขอย่างเป็นทางการและเรียกใช้

import String as S
import Char (..)
import Graphics.Input (..)
import Graphics.Input.Field (..)
f="ETAOINSHRDLCUMWFGYPBVKJXQZ"
r s n=let t c=mod(toCode c-65+n)26+65 in map(fromCode . t)(S.toList s)
w s=case s of 
 ""->0
 s->sum(S.indexes(S.left 1 s)f)+w(S.dropLeft 1 s)
b s=sort<|map(\x->((w . S.fromList . r s)x,(26-x,S.fromList<|r s x)))[0..25]
c=input noContent
main=above<~(field defaultStyle c.handle id""<~c.signal)~(asText . b . .string<~c.signal)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.