নিদর্শন বিশ্লেষণ দ্বারা ডিক্রিপশন


11

আপনাকে একটি এনক্রিপ্ট করা স্ট্রিং দেওয়া হয়েছে, খুব সাধারণ সাবস্টিটিউশন সাইফার ব্যবহার করে এনক্রিপ্ট করা হয়েছে।

সমস্যা

সাইফারটি কী তা আপনি জানেন না তবে আপনি জানেন যে সাইফারেক্সটেক্সটি ইংরেজি এবং ইংরেজিতে সর্বাধিক ঘন অক্ষরগুলি সেই ক্রমে ইটাওনশার্ডলুক্মফুইভিভিভিজিবিকিজেজেজ হয়। কেবলমাত্র অনুমোদিত অক্ষরগুলি বড় হাতের অক্ষর এবং স্পেস space আপনি মৌলিক বিশ্লেষণ করতে পারেন - একক অক্ষর থেকে শুরু করে, তবে আপনি আরও জটিল মাল্টি-লেটার বিশ্লেষণে স্থানান্তর করতে পারেন - উদাহরণস্বরূপ, ইউ প্রায় সর্বদা Q অনুসরণ করে এবং কেবলমাত্র কয়েকটি অক্ষর পরপর দু'বার আসতে পারে।

উদাহরণ

clear : SUBMARINE TO ATTACK THE DOVER WAREHOUSE AND PORT ON TUESDAY SUNRISE
cipher: ZOQ DUPAEYSRYDSSDXVYSHEYNRBEUYLDUEHROZEYDANYKRUSYRAYSOEZNDMYZOAUPZE

clear : THE QUICK BROWN FOX BEING QUITE FAST JUMPED OVER THE LAZY DOG QUITE NICELY
cipher: TNAEPDHIGEMZQJLEVQBEMAHL EPDHTAEVXWTEODYUASEQKAZETNAERXFCESQ EPDHTAELHIARC

clear : BUFFALO BUFFALO BUFFALO BUFFALO BUFFALO BUFFALO BUFFALO
cipher: HV  WRPDHV  WRPDHV  WRPDHV  WRPDHV  WRPDHV  WRPDHV  WRP

চ্যালেঞ্জ

দেখুন আপনি এই সাইফারের প্রত্যেকটিতে লেখাটি ডিক্রিপ্ট করতে পারবেন কিনা:

  • SVNXIFCXYCFSXKVVZXIHXHERDXEIYRAKXZCOFSWHCZXHERDXBNRHCXZR RONQHXORWECFHCUH
  • SOFPTGFIFBOKJPHLBFPKHZUGLSOJPLIPKBPKHZUGLSOJPMOLEOPWFSFGJLBFIPMOLEOPXULBSIPLBP KBPBPWLIJFBILUBKHPGKISFG
  • TMBWFYAQFAZYCUOYJOBOHATMCYNIAOQW Q JAXOYCOCYCHAACOCYCAHGOVYLAOEGOTMBWFYAOBFF ACOBHOKBZYKOYCHAUWBHAXOQW XITHJOV WOXWYLYCU
  • FTRMKRGVRFMHSZVRWHRSFMFLMBNGKMGTHGBRSMKROKLSHSZMHKMMMMMRVVLVMPRKKOZRMFVDSGOFRW

আমার প্রত্যেকের জন্য বিকল্প ম্যাট্রিক্স এবং স্পষ্ট পাঠ্য রয়েছে, তবে আমি কেবল তখনই তা প্রকাশ করব যদি এটি খুব বেশি কঠিন হয়ে যায় বা কেউ তা না বের করে।

যে সমাধানটি সর্বাধিক বার্তা সফলভাবে ডিক্রিপ্ট করতে পারে তা হ'ল বিজয়ী। দুটি সমাধান যদি সমানভাবে ভাল হয় তবে তাদের ভোট গণনা দ্বারা সিদ্ধান্ত নেওয়া হবে।


3
»সবচেয়ে মার্জিত def কোনটি সংজ্ঞায়িত করে? আমি মনে করি এটি ইতিমধ্যে 99 বোতলগুলিতে ক্রিস আপত্তি করেছিল। এটি একটি বিষয়গত মানদণ্ড যা বিচার করা বেশ শক্ত।
জোয়ে

@ জোয়ি বেশিরভাগ আপভোটস? সম্প্রদায় সিদ্ধান্ত নিতে দিন।
থমাস হে

2
পুনরায় "সর্বাধিক উন্নতি": এটি জনপ্রিয়তা প্রতিযোগিতামূলক পোস্টে পরিণত হতে পেরে আমি অসন্তুষ্ট, পোস্টটি অন্যথায় দুর্দান্ত হওয়ার কারণে নয়; পুরো বিষয়টি সম্পর্কে আমার চিন্তাধারার জন্য meta.codegolf.stackexchange.com/questions/110/… দেখুন ।
ক্রিস জেস্টার-ইয়ং

2
"মার্জিত" এর অর্থ এখানে কী? সেরা বিগ-ও পারফরম্যান্স?
gnibbler

1
@ বাস 5098, না। এটি কেবল একটি জটিল সাইফারেক্সট যা এটি ফ্রিকোয়েন্সি বিশ্লেষণকে আরও স্থিতিশীল করতে দাগযুক্ত করা হয়েছে।
থমাস হে

উত্তর:


9

পাইথন

আমি সমস্ত গোপন বাক্য খুঁজে বের করেছি, তবে আমি সেগুলি এখানে পোস্ট করব না। আপনি যদি যত্ন নেন তবে কোডটি চালান।

কোডটি একটি শব্দের জন্য সমস্ত সম্ভাব্য বিকল্প গণনা করে, তারপরে সামঞ্জস্যপূর্ণ বিকল্পগুলি অনুসন্ধান করে একটি স্পেস অক্ষর বাছাই করে কাজ করে। এটি ক্লিয়ারটেক্সটে ভুল বানান নিয়ে কাজ করার জন্য কিছু অ-বহিরাগত অভিধানের জন্য অনুমতি দেয় :)

আমি http://wordlist.sourceforge.net/ থেকে একটি বৃহত অভিধান (~ 500 কে শব্দ) ব্যবহার করেছি ।

import sys,re

# get input
message = sys.argv[1]

# read in lexicon of words
# download scowl version 7.1
# mk-list english 95 > wordlist
lexicon = set()
roman_only = re.compile('^[A-Z]*$')
for word in open('wordlist').read().upper().split():
  word=word.replace("'",'')
  if roman_only.match(word): lexicon.add(word)

histogram={}
for c in message: histogram[c]=0
for c in message: histogram[c]+=1
frequency_order = map(lambda x:x[1], sorted([(f,c) for c,f in histogram.items()])[::-1])

# returns true if the two maps are compatible.
# they are compatible if the mappings agree wherever they are defined,
# and no two different args map to the same value.
def mergeable_maps(map1, map2):
  agreements = 0
  for c in map1:
    if c in map2:
      if map1[c] != map2[c]: return False
      agreements += 1
  return len(set(map1.values() + map2.values())) == len(map1) + len(map2) - agreements

def merge_maps(map1, map2):
  m = {}
  for (c,d) in map1.items(): m[c]=d
  for (c,d) in map2.items(): m[c]=d
  return m

def search(map, word_maps, outside_lexicon_allowance, words_outside_lexicon):
  cleartext = ''.join(map[x] if x in map else '?' for x in message)
  #print 'trying', cleartext

  # pick a word to try next
  best_word = None
  best_score = 1e9
  for (word,subs) in word_maps.items():
    if word in words_outside_lexicon: continue
    compatible_subs=0
    for sub in subs:
      if mergeable_maps(map, sub): compatible_subs += 1
    unassigned_chars = 0
    for c in word:
      if c not in map: unassigned_chars += 1  #TODO: duplicates?
    if compatible_subs == 0: score = 0
    elif unassigned_chars == 0: score = 1e9
    else: score = 1.0 * compatible_subs / unassigned_chars   # TODO: tweak?
    if score < best_score:
      best_score = score
      best_word = word
  if not best_word:  # no words with unset characters, except possibly the outside lexicon ones
    print cleartext,[''.join(map[x] if x in map else '?' for x in word) for word in words_outside_lexicon]
    return True

  # use all compatible maps for the chosen word
  r = False
  for sub in word_maps[best_word]:
    if not mergeable_maps(map, sub): continue
    r |= search(merge_maps(map, sub), word_maps, outside_lexicon_allowance, words_outside_lexicon)

  # maybe this word is outside our lexicon
  if outside_lexicon_allowance > 0:
    r |= search(map, word_maps, outside_lexicon_allowance - 1, words_outside_lexicon + [best_word])
  return r

for outside_lexicon_allowance in xrange(3):
  # assign the space character first
  for space in frequency_order:
    words = [w for w in message.split(space) if w != '']
    if reduce(lambda x,y:x|y, [len(w)>20 for w in words]): continue  # obviously bad spaces

    # find all valid substitution maps for each word
    word_maps={}
    for word in words:
      n = len(word)
      maps = []
      for c in lexicon:
        if len(c) != n: continue
        m = {}
        ok = 1
        for i in xrange(n):
          if word[i] in m:                      # repeat letter
            if m[word[i]] != c[i]: ok=0; break  # repeat letters map to same thing
          elif c[i] in m.values(): ok=0; break  # different letters map to different things
          else: m[word[i]]=c[i]
        if ok: maps.append(m);
      word_maps[word]=maps

    # look for a solution
    if search({space:' '}, word_maps, outside_lexicon_allowance, []): sys.exit(0)

print 'I give up.'

1

পিএইচপি (অসম্পূর্ণ)

এটি একটি অসম্পূর্ণ পিএইচপি সমাধান যা প্রদত্ত শব্দের মধ্যে সবচেয়ে নির্ভরযোগ্য অক্ষরের উপর নির্ভর করে নিয়মিত প্রকাশের সাথে শব্দের অক্ষরের ফ্রিকোয়েন্সি তথ্য এবং শব্দগুলির একটি অভিধান ব্যবহার করে কাজ করে।

বর্তমানে অভিধানটি বেশ ছোট তবে উপযুক্ত সম্প্রসারণের সাথে আমি প্রত্যাশা করছি যে ফলাফলগুলি উন্নতি করবে। আমি আংশিক ম্যাচের সম্ভাবনা বিবেচনা করেছি কিন্তু বর্তমান অভিধানের সাথে ফলাফলের উন্নতির পরিবর্তে অবনতি ঘটে।

এমনকি বর্তমান, ছোট অভিধানের সাহায্যেও আমি মনে করি চতুর্থ বার্তাটি কীভাবে এনকোড করে তা আমি নিরাপদে বলতে পারি।

#!/usr/bin/php
<?php

    if($argv[1]) {

        $cipher = $argv[1];

        // Dictionary
        $words = explode("/", "the/to/on/and/in/is/secret/message");
        $guess = explode("/", "..e/t./o./a../i./.s/.e..et/.ess..e");

        $az = str_split("_etaoinshrdlucmfwypvbgkqjxz");

        // Build table
        for($i=0; $i<strlen($cipher); $i++) {
            $table[$cipher{$i}]++;
        }
        arsort($table);

        // Do default guesses
        $result = str_replace("_", " ", str_replace(array_keys($table), $az, $cipher));

        // Apply dictionary
        $cw = count($words);
        for($i=0; $i<$cw*2; $i++) {
            $tokens = explode(" ", $result);
            foreach($tokens as $t) {
                if(preg_match("/^" . $guess[$i%$cw] . "$/", $t)) {
                    $result = deenc($words[$i%$cw], $t, $result);
                    echo $t . ' -> ' . $words[$i%$cw] . "\n";
                    break;
                }
            }
        }

        // Show best guess
        echo $result . "\n";

    } else {

        echo "Usage: " . $argv[0] . " [cipher text]\n";

    }

    // Quick (non-destructive) replace tool
    function deenc($word, $enc, $string) {
        $string = str_replace(str_split($enc), str_split(strtoupper($word)), $string);
        $string = str_replace(str_split($word), str_split($enc), $string);
        return strtolower($string);
    }

?>

/ ইউএসআর / শেয়ার / ডিক / শব্দ ব্যবহার করার চেষ্টা করুন যদি আপনি এটির কোনও সিস্টেমে থাকেন।
কিথ র্যান্ডাল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.