XKCDパスワードジェネレーター


34

前書き

どうやら、この質問はここで尋ねられおり、残念ながら終了しました。もう一度試してみるのは良い考えだと思いましたが、正しくやっていました。

XKCDは、「覚えにくいパスワード」を使用するように訓練されている方法を見て、安全だと思いますが、代わりにコンピューターをクラックするのに3日かかります。反対に、4〜5語を覚えると、Kuanのパスワードイントロピーが高まり、覚えやすくなります。クレイジーだよね?

チャレンジ

今日の仕事は、単語を使用して5つのパスワードを作成することです。パスワードごとに4単語、単語ごとに最低4文字、ただし最大値はありません。Kuanのパスワードイントロピーは、すべてのパスワードについて計算する必要がありますが、強制的な最小値は設定されません。

Kuanのパスワードイントロピーとは何ですか?

Kuanによると、Kuanのパスワードイントロピーは、パスワードがどれほど予測不能であるかの尺度です。単純な計算があります:Eは=ログ2(R)* Lを。EはKuanのパスワードイントロピー、Rは使用可能な文字の範囲、Lはパスワードの長さです。

利用可能な文字の範囲は自明です。パスワードに使用できる文字の範囲です。この場合、大文字と小文字です。アルファベットには26文字あるため、パスワードの全範囲で26 x 2 = 52文字です。

パスワードの長さも自明です。作成後のパスワードの合計の長さです。

制約

  • 入力なし。
  • 同じパスワードで単語を再表示することはできません
  • パスワードには記号や数字を使用できません。
  • パスワードごとに4ワード、ただしワードごとに最低4文字。
  • 単語間にスペースはありません。
  • 同じパスワードを何度も生成することはできません。
  • 各単語はパスワードで大文字にする必要があります。
  • 出力は人間が読めるものでなければならず、間隔をあける必要があります。上記のKuanのパスワードイントロピー式を使用して、パスワードのKuanのパスワードイントロピーも含める必要があります。
  • 辞書。これを使用し、テキストファイルとしてダウンロードし、それに応じて統合する必要があります。これは、単語を取得するリストになります。コードは利用可能であると想定する必要があります。
  • これは、最短バイトが勝ちます。

出力

TriedScarProgressPopulation 153.9
TryingPastOnesPutting 119.7
YearnGasesDeerGiven 108.3
DoubtFeetSomebodyCreature 142.5
LiquidSureDreamCatch 114.0

16
テストケースの場合、パスワードエントロピーが変化するのはなぜですか?同じ辞書から生成される4ワードのパスワードはすべて、同じエントロピーを持つ必要があります。
NonlinearFruit

20
パスワードエントロピーは、シンボルセットに依存しています。パスワードがNセットのシンボルである場合S、パスワードエントロピーはlog2(|S|)*Nです。ここで、シンボルセットのサイズは辞書のサイズ(|S|=4284)、シンボルの数は単語の数(N=4)であるため、各パスワードのエントロピーは48.3です。
NonlinearFruit

48
このエントロピーの定義は危険なほど間違っています!各文字がサイズRのセットから一様にランダムに選択される場合、実際には長さLのパスワードにはR ^ Lの可能性があるため、エントロピーはその対数です。log₂(R ^ L)=log₂(R)* Lあなたの式です。ただし、パスワードが別のセットからランダムに選択された場合(たとえばのようなパスワードは決してない3t1ta#asd)、エントロピーは可能なパスワードの数の対数になります。4284語辞書から常にランダムに4語をランダムに選択する場合、4284 ^ 4個のパスワードがあり、それぞれにエントロピーlog₂(4284)* 4≈48.26があります。
シュリーバツァー

5
記録のために、この種のパスワードはXKCD漫画よりも前のものです。それらは「ダイスウェア」パスワードと呼ばれます。
user2428118

5
ランダムな文字よりもエントロピーが少ない単語の問題は別として、あなたの質問は単語を大文字にする必要があります。つまり、大文字と小文字は固定され、エントロピーとしてカウントされません。
ニートザダークアブソル

回答:


13

Python 2、102 101 97 91バイト

from random import*
exec"x=''.join(x.title()for x in sample(f,4));print(x,57*len(x)/10);"*5

辞書をという名前のリストと見なしfます。

ファイルを次の名前で保存してテストできます dict.txt呼び出す

f = open('dict.txt').readlines()

Pythonリストにはシャッフルメソッドはありません。また、括弧を削除することでPython 2で2バイトを節約できますexecexecPython 2のキーワードです)。
コンラッドボロ

@xfixそうshuffle(f);です。
ジョナサンアラン

おっと、できるだけ早く修正
Martmists

4
浮動小数点エラーが発生しない限り、5.7での丸めは小数点以下1桁までであることに注意し、で5バイトを節約するという私のトリックを使用できます57*len(x)/10.。括弧を削除して印刷をタプルにすることにより、別のバイトを保存します。ここでは、カットダウンバージョンは次のとおりです。TIO
ジョナサン・アラン

sample(f,4)代わりに使用しますshuffle。また、fちょうどすることができopen('dict.txt').read().split('\n')open('dict.txt').readlines()またはちょうどopen('dict.txt')(私はまだそれがgolfedていない知っているが)。
アレックスホール

10

PowerShell(3.0 +)、77バイト

1..5|%{($p=-join($d|random -c 4|%{culture|% te*|% tot* $_}));57*$p.Length/10}

オンラインでお試しください!

を使用して Jonathan Allan57*len/10トリックます。

$d辞書が単語の配列として含まれています。自宅でプレイしていて、埋めたい場合$d

$d=-split(irm pastebin.com/raw/eMRSQ4u2)

ゴルフバージョンの使用 (Get-Culture).TextInfo.ToTitleCase()、最初の文字を大文字にします。PowerShellでこれを行う簡単な方法はないと思います。

残りは非常に簡単です。

TIOリンクには辞書全体が含まれています。キャッシュを無効にして気をつけてください!


誰かが「ジョナサンアランの57 * len / 10トリック」のリファレンスを教えてくれますか?
ジェームズカラン


これは2.0では正しく機能しません。タイトルに注意する必要があります。また$d、環境内に存在するものと想定して読む必要があると思います。(gc d)| random..ここで、辞書は同じディレクトリにあるdというファイルです。
マット

1
@Matt on SO私は答えをv2で動作させる(または2つのバージョンを実行する)ために邪魔になるかもしれませんが、これはコードゴルフマンです!より不可解であるほど良い;-p
ブライアンティスト

1
回答のタイトルにバイトを保存しようとしています。
マット

7

ゼリー、22 バイト

Ẋḣ4ŒtFµL×57÷⁵⁸,K
çЀ5Y

文字のリストのリストをとるモナドリンク、解析された辞書(チャットで許可されている)。

オンラインでお試しください!(「引数」をクリックして辞書を非表示にし、スクロールの必要性を減らします。)

どうやって?

辞書には有効な単語(4文字以上、[a-z])ないため、この条件を確認する必要はありません。

以来、辞書内のすべての単語はの長されている[4-8]可能性パスワードの長さはであり[16,32]、可能なエントロピーは決してラウンド異なり、小数点以下1桁に置き換えることによってよりますlog(52,2)5.7。唯一の問題は、の浮動小数点値を使用することである5.7長さについて丸め誤差浮動小数点を与えるであろう182631。しかしを乗算57し、その後で割る10使用する×57÷⁵(まだ使用して完全な浮動小数点精度の値を印刷するよりも短いバイトでありながら、これを回避します×52l2¤)。

çЀ5Y - Main link: list of list of characters (the parsed dictionary)
   5  - literal 5
 Ѐ   - map across the implicit range [1,2,3,4,5]:
ç     -   last link (1) as a dyad
    Y - join with newlines
      - implicit print

Ẋḣ4ŒtFµL×57÷⁵⁸,K - Link 1, get password and entropy: list of lists of characters, number
Ẋ                - shuffle the list of lists (shuffle all the words)
 ḣ4              - head to 4 (the first four words)
   Œt            - title case (make the first letter of each uppercase)
     F           - flatten into one list of characters
      µ          - monadic chain separation, call that p
       L         - length of p
         57      - 57
        ×        - multiply
            ⁵    - 10
           ÷     - divide -> entropy to 1 decimal place
             ⁸   - link's left argument, p
              ,  - pair -> [p, entropy]
               K - join with (a) space(s)

5

ルビー、89 83バイト

d.select!{|w|w[3]}
5.times{p w=d.sample(4).map(&:capitalize)*'',5.700439718*w.size}

パスワードが変数に格納されていると仮定しますd。コードの前に次の行を追加できます。

d=$<.map(&:chomp)

そして、例えば次のようなスクリプトを呼び出します:

$ ruby generate_passwords.rb < dictionary_file.txt

サンプル出力:

"MarginStarvedOnusInsulted"
142.51099295
"KitchenMiseryLurkJoints"
131.110113514
"InducesNotablePitfallsPrecede"
165.312751822
"FarmersAbortFutileWrapper"
142.51099295
"RoutesBishopGlowFaithful"
136.81055323200002

KitchenMiseryLurkJoints ...うわー。


Ajedi32から-6バイト


1
除去することにより、数バイトを保存することができるかもしれないshuffle!と交換popsample
Ajedi32

@ Ajedi32ああ、あなたは正しい!私は実際にそれについて考えましたが、すべてのパスワードA word cannot reappear in the same passwordで単語を再利用しないことを意味すると考えて、このルールを読み間違えました。ありがとう:)
daniero

4

Mathematica、178バイト

t=1;l=Length;While[t<6,s=RandomChoice[Import["https://pastebin.com/raw/eMRSQ4u2"],4];c=Capitalize/@s;f=Flatten@Characters[c];Print[StringJoin[c]," ",Log[2,l@Union@f]*l@f//N];t++]

オンラインで試す

ctrl-vを使用してコピーして貼り付け、shift + enterを押して実行します


Mathematica、136バイト

mが辞書であると仮定すると、コードは

m=ImportString[Import["C:\a.txt"]]

t=1;l=Length;While[t<6,s=RandomChoice[m,4];c=Capitalize/@s;f=Flatten@Characters[c];Print[StringJoin[c]," ",Log[2,l@Union@f]*l@f//N];t++]

「今日の仕事は、単語を使用して5つのパスワードを作成することです。」1つではなく5つが必要です。
-KuanHulio

ok ... 5個のパスワード..修正済み。
J42161217

ハイパーリンクテキストを避けてコードを短縮するために、辞書をローカルで利用可能にしたのはなぜですか?
セルジオ

簡単にテストできるようにするために
...-J42161217

テストを簡単にするため、自己完結型であるように提出物を少なくするよりも、単純な、未使用のヘルパーコードを提供するのが最善です。また、ローカルDNSサーバーをハイジャックする(またはhostsファイルを変更する)ことなく、辞書は可変であると想定されています。
-wizzwizz4

4

バッシュ66 65バイト

for w in `shuf -n4 -`;{((l+=${#w}));printf ${w^};};bc<<<$l*5.7004

オンラインでお試しください!

辞書はSTDINによって受信されます。辞書内のすべての単語をシャッフルし、最初の4を出力します。

単語ごとに、var lの長さを合計し、大文字で単語をエコーし​​ます。最後にbcを呼び出して計算を行います。

Awkソリューション、112バイト、4つのパスワード:

shuf -n16 -|xargs -n4|awk '{for(i=1;i<5;i++)printf toupper(substr($i,1,1))substr($i,2);print(length($0)-3)*5.7}'

3

(これはマートミストの答えを修正したものですが、コメントする担当者がいません)

Python、88 86バイト

g={*f}
exec('x="".join(g.pop().title()for i in "a"*4);print(x,len(x)*5.700439718);'*5)

set非決定的である方法を活用することにより、ランダム性ライブラリをインポートする必要がなくなります。


これにより、一貫して同じ出力が生成されます。何らかの実装で動作する場合は、実行することで数バイトを節約できますset(f).pop()
ジョナサンアラン

1
これは本当に有効だとは思いません。確定的ではないため、同じパスワードを生成することは保証されていませんが、実際には異なる結果を作成することはほとんどありません。
DJMcMayhem

実装に依存するのではないかと疑っていました。新しくインストールしたAnaconda Python 3のWindowsリリースでそれを行いましたが、うまくいきました。しかし、set(f).pop()動作しません、私はそれを試しました。毎回同じ結果が得られます。
デイン

「実際には、それはめったに異なる結果を作成していないだろう」 -それは私のためにそうです、ここではサンプルです:pastebin.com/raw/ZHiHgzxV
デイン

@dain私は興味があります。Pythonビルドに関する情報を提供してください。
wizzwizz4

3

Japt、30バイト

5Ç[V=Uö4 ®g u +Zt1ìMm52 *Vl]¸

オンラインでお試しください!


いいね!しかし残念ながら、それは同じパスワードを5回作成し、それが異なっている必要がありますたびに...
イアン・ウォード

これは30文字かもしれませんが、少なくともUTF-8では、私のシステムは35バイトでクロックします。
CVn

1
@MichaelKjörlingJaptはUTF-8ではなくISO 8859-1を使用します。
デニス

@デニス興味深い。ありがとうございました。
CVn

3

JavaScript(ES6)、164バイト

d=>{for(i=5;i--;)console.log(p="....".replace(/./g,_=>(w=d.splice(Math.random()*d.length|0,1)[0])[0].toUpperCase()+w.slice(1)),(Math.log2(52)*p.length).toFixed(1))}

辞書が配列として関数に渡されると仮定します。

テストスニペット


2

Mathematica、71バイト

辞書が既にと呼ばれる配列にロードされていると仮定しdます。

Table[{#,Log[2,52]StringLength[#]}&[""<>Capitalize@d~RandomSample~4],5]

説明:

                                        Capitalize@d                    - Capitalize all the dictionary
                                                    ~RandomSample~4     - make an array with 4 values. By default values can not repeat.
                                    ""<>                                - Concatenate with empty string to turn array into single string.
      {#,Log[2,52]StringLength[#]}&[                               ]    - Put current string next to log(2,52) times length of current string
Table[                                                              ,5] - Repeat this 5 times.

エントロピー数はどうですか?!
ジョナサンアラン

おっと、そのビットを逃しました。更新しました。
イアンミラー

2

ColdFusion 216バイト

p={};z=arrayLen(c);for(x=0;x<5;x++){pw="";r={};while(structCount(r)<4){n=RandRange(1,z);r.append({"#c[n]#":true});}for(w in structKeyList(r)){pw&=REReplace(w,"\b(\w)","\u\1","All");};p.append({"#pw#":57*len(pw)/10})}

これは、ColdFusion 11以降およびLucee 4.5以降で機能します。

実行するには: https //trycf.com/gist/ff14e2b27d66f28ff69ab90365361b12/acf11?theme=monokai

TryCFリンクには、ゴルフっぽくないが同じコードがあります。

競争力のあるゴルフの答えを期待していませんでした。ColdFusionでこの課題を完了するために必要なものを確認したかっただけです。特に、これらの回答には多くのCFがないためです。:-)セットアップ後、予想以上に短くなりました。

私の最初の試みは、同じ単語を複数回使用できないことを思い出すまで、少し短くなりました。ランダマイザーが同じインデックスを複数回選択することはほとんどありませんが、構造のキーにインデックスをダンプすることで、重複を防ぎます。次に、そのキーのリストを使用して、最終的なパスワード文字列を作成します。また、数学のトリックを使用してエントロピーを見つけました。


2

PHP136 129バイト

-7バイト、Jörgに感謝

for(shuffle($a);$i++<5;){for($s='',$c=0;$c<4;)strlen($w=$a[$k++])<4?:$s.=ucfirst($w).!++$c;echo$s.' '.log(52, 2)*strlen($s)."
";}

オンラインでお試しください!


@JörgHülsermannそれはうまくいくようです、ありがとう。
ME

2

Python 3、252バイト

これは私がやった初めてのコードゴルフチャレンジです!私はここに他のPythonの答えがあることを知っています(おそらく私のものよりも良いでしょう)が、これは面白そうだったので、とにかく試してみたかったです。ここにゴルフバージョンがあります:

import random, math
with open("d") as f: d=f.read()
l=d.split()
for a in range(5):
 u=[]
 p=""
 for b in range(4):
  w=random.choice([w for w in l if not w in u and len(w)>=4])
  u.append(w)
  w=w.title()
  p+=w
 print("%s %s"%(p,math.log2(52)*len(p)))

Try it Onlineを投稿します!リンクが、それは複数のファイルをサポートしていません。ここにrepl.itリンクがあります:https ://repl.it/InIl/0

また、ここには非ゴルフバージョンがあります:

import random
import math
with open("d") as f:
    dictionary = f.read() #this is the dictionary text file, simply saved as "d" as to use as few bytes as possible
words = dictionary.split() #here we turn that dictionary string into a list
for a in range(5): #here we iterate through 5 passwords
    used_words = []
    password = ""
    for b in range(4): #here we iterate through the 4 words in each password
        word = ""
        word = random.choice([word for word in words if not word in used_words and len(word) >= 4]) #Thanks to blackadder1337 from #python on freenode IRC for helping me with this.
        used_words.append(word)
        word = word.title()
        password = password + word
    print("%s %s"%(password, math.log2(52) * len(password)))

私が言ったように、これは初めてコードをゴフリングするので、これは大幅に改善されると確信しています。


PPCGへようこそ!
テイラースコット

2

tcl、137

確かに勝者ではありませんが、もう少しゴルフができると思います。

time {set p "";time {set p [string totitle [lindex $d [expr int(rand()*[llength $d])]]]$p} 4;puts $p\ [expr 5.7004*[string length $p]]} 5

demo — 1行目の目的は、辞書の内容を変数に入れることだけですd


パスワードには5語ではなく4語が必要なので、たぶんゴルフできます。
KuanHulio

そして、4ではなく5つのパスワードを要求しました。数字が合わなかった!
-sergiol

ハハハ!@sergiol
KuanHulio

一定!@KuanHulio
セルジオル

それは良いです。良くやった。
-KuanHulio

0

Vim、87キーストローク

qq:r!echo "$RANDOM"l<CR>D:w o|e w<CR>@"ev4bd:w|bp<CR>p0~wX~wX~wX~Y:.!wc -c<CR>A*5.7003<Esc>:.!bc<CR>PJq4@q

辞書がという名前のファイルにあると仮定しますw。常に4つの連続した単語を使用します

説明:

qq                       Start recording a macro named 'q'
:r!echo "$RANDOM"l<CR>   Append the result of the shell command `echo "$RANDOM"l`
D                        Delete what you just appended
:w o|                    Save the buffer to the file 'o' and ..
e w<CR>                  Open the file 'w'
@"                       Execute the text we deleted as a normal-mode command
                         This will move the cursor a random number of characters
                         to the right
e                        Go to the end of the next word
v4bd                     Delete 4 words backwards
:w|                      Save the file and ..
bp<CR>                   Open the last buffer (the 'o' file)
p                        Paste the 4 words we deleted
0                        Move the cursor to the beginning of the line
~wX~wX~wX~               Remove the spaces between the words and capitalize
Y                        Copy current line
:.!wc -c<CR>             Pipe the current line through 'wc -c'
A*5.7003<Esc>            Append "*5.7003" to the end of the line
:.!bc<CR>                Pipe the current line through 'bc'
P                        Paste the password above the current line
J                        Join with line bellow
q                        Stop recording the 'q' macro
4@q                      Run the 'q' macro 4 times

0

q / kdb +、76 74 65 56バイト

溶液:

{(x;5.70044*(#)x)}(,/)@[;0;upper]each -4?" "vs(*)(0:)`:w

例:

q){(x;5.70044*(#)x)}(,/)@[;0;upper]each -4?" "vs(*)(0:)`:w
"RulingOverheadSaddensPriest"
153.9119

説明:

単語リストを読んで、「」で分解し、このリストから4つのランダムな単語を選択し、各単語の最初の文字を大文字にして、結合します。これを、パスワードと計算された「エントロピー」を返すラムダ関数に送ります。

                                                     `:w / the wordlist is a file called 'w'
                                                 (0:)    / read in the file list (\n separated list)
                                              (*)        / take first (and only) item in the list
                                         " "vs           / split this on " "
                                      -4?                / take 4 random items from this list, neg means 'dont put back'
                      @[; ;     ]                        / apply a function to variable at indices (variable is implicit)
                           upper                         / uppercase (the function being applied)
                         0                               / index 0, the first character
                                 each                    / each of the 4 random items
                  (,/)                                   / 'raze' (flatten lists)
{                }                                       / anonymous lambda function
 (x;            )                                        / a 2-item list, x is first item
            (#)x                                         / count x, return the length of the list
    5.70044*                                             / multiply by 5.70044

ノート:

私は代わりに5.70044を使用しました2 xlog 52 xexp...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.