Escreva um programa que execute a combinação de letras de força bruta até que a palavra “senha” seja encontrada


16

O programa deve imprimir todas as combinações de letras (minúsculas ou maiúsculas, não importa) em ordem alfabética. Ele deve começar com ae a última combinação impressa deve ser password.

A saída deve ser:

a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ... passwora passworb passworc password

2
Os separadores precisam ser espaços ou posso usar novas linhas?
Ilmari Karonen 23/09

Sim, você pode, é apenas uma pequena mudança.
ST3 24/09

Respostas:


32

Perl, 19 caracteres

say for a..password

Usa novas linhas como delimitadores, conforme esclarecimento acima. Execute com perl -M5.010(ou apenas perl -E 'say for a..password') para ativar o Perl 5.10+say recurso . Por meta , isso não conta como caracteres extras.

(Se você insiste em espaços como delimitadores, $,=$";say a..passwordé apenas dois caracteres a mais. No entanto, também é muito lento e desperdício de memória, a ponto de ser inutilizável na prática, pois ele tenta criar a lista inteira na memória antes de imprimi-la.)


18

Ruby, 33 caracteres (versão ideal, mas mais longa)

?a.upto('password'){|c|$><<c+' '}

Eu gosto do 'a'.upto('password'); diz exatamente o que está fazendo. Ruby é ótimo e expressivo assim.:D

Claro, print c,' 'também seria muito mais claro, mas usar $>é dois caracteres menor.

Ruby, 29 25 caracteres (versão lenta)

$><<[*?a..'password']*' '

Este é mais curto, mas imprime todos os tokens de uma só vez, por isso leva muito, muito tempo para ser executado!


11
Bom, especialmente o primeiro.
Cary Swoveland

Na versão lenta, (?a..'password').to_apode ser reduzido para[*?a..'password']
Paul Prestidge

6

Perl, 33 32 24 caracteres

Uma solução em 32 caracteres:

$_=a;print$_++,$"until/passwore/

Não há muito a dizer sobre este. Eu poderia reduzir isso para 27 caracteres se pudesse usar novas linhas em vez de espaços para separar as entradas.

Ilmari Karonen ressalta que ..chamadas internamente ++, portanto, uma solução melhor (25 caracteres) seria:

print$_,$"for a..password

Aproveitando as opções de linha de comando do Perl, aqui está uma solução equivalente a 24 caracteres:

perl -l40e 'print for a..password'

As regras para a contagem de sinalizadores perl estão aqui, para aqueles que não estão familiarizados com eles.

Obviamente, a solução de 21 caracteres da Ilmari ainda é mais curta, mas requer uma máquina que possa alocar uma matriz de 129.052.722.140 strings.


Em .$"vez de ," "salvar um personagem, não seria ?
Llama

Sim, supervisão total da minha parte. Obrigado.
embalagem de pão

6

Perl 6, 20 caracteres

say "a".../password/

Você não precisa de outras coisas


5

Python 2, 91

b=lambda n:n*' 'and b(n/26-(n%26<1))+chr(~-n%26+97)
i=0
exec"i+=1;print b(i);"*129052722140

4

PHP 38. 37. 36 caracteres

<?for($w=a;$w<passwore;)echo$w++,~ß;

Você deve definir a codificação para ISO 8859-1 e desativar os avisos.


Eu não testei isso, mas realmente faz isso ???
ST3 25/09

@ ST3 É um loop simples. A variável $wé inicialmente definida como 'a' e depois é incrementada até atingir o primeiro valor após 'senha' (a última sequência não é impressa).
Lortabac

3
@ ST3 É um forloop regular . Não há nada de estranho nesse código, exceto os dois últimos caracteres, que são um espaço em branco invertido em bits. Enfim, sim, eu testei até uma palavra mais curta.
Lortabac

11
@ ST3 Aqui está um teste de passwoqsaté password. Como a codificação do codepad não é ISO 8859-1, tive que substituir por um espaço em branco.
Lortabac # /

11
Você pode salvar um caractere $w<passworeno lugar de $w!=passwore.
Decent Dabbler

2

Ruby (40 caracteres)

Interprete uma sequência de letras az como um número na base 26, com a = 1, b = 2, ..., z = 26.

Portanto, "senha" pode ser pensada como o número N =

16*(26**7) + 
1*(26**6) + 
19*(26**5) + 
19*(26**4) + 
23*(26**3) + 
15*(26**2) + 
18*(26**1) + 
4*(26**0)

Se deixarmos s = "a"(isto é: 1) e fizermos (N-1) chamadas para s.succ!, s será "password"(N). Em outras palavras, N = 1 + (N-1).

Para um exemplo que será executado mais rapidamente, para provar que o cálculo de N está correto, considere "pass"como o destino, onde N é

16*(26**3) + 
1*(26**2) + 
19*(26**1) + 
19*(26**0)

e

s = "a"
(N-1).times { s.succ! }
puts s #== "pass"

Como também queremos imprimir "a", precisamos

s = "`"
N.times { print(s.succ! + " ") }

Então, volte para a "senha" completa. N = 129052722140, deixando:

s=?`;0x1e0c2443dc.times{$><<s.succ!+" "}

Eu procurei por uma forma mais compacta, 129052722140 == 0x1e0c2443dbmas não consegui encontrar uma.

(Atualizado para corrigir a falta de impressão "a", graças a Cary.)


11
Adam, deve ter sido você na minha mente. Você não quer iniciar um antes de 'a'?
Cary Swoveland

Acho que você está entendendo que eu usei em Nvez de N-1nas iterações! Obrigado, vou editar para corrigir. (Embora 129052722140 é um número interessante Google :).)
Adam Prescott

11
0x1e0c2443db é tão muitos caracteres como 129052722139.
steenslag

O que eu quis dizer foi que se s=?a, s.succ!começa em 'b' '.
Cary Swoveland

11
Com s=?ae N-1você obtém 'b c ... password'; com s =<backtick> e Nvocê obtém 'a b ... senha'. O SO solicitou a saída para começar 'a'. Isso é tudo.
Cary Swoveland

2

Javascript, 73

Aqui está uma versão com 73 caracteres do código @Briguys ', que imprime apenas combinações de letras

for(i=s=0;1982613533018>i++;s=i.toString(36))/\d/.test(s)||console.log(s)


2

APL (Dyalog), 46 34

{∇{'PASSWORD '≡⍞←⍵:→⋄⍵}¨⎕A∘.,⍵}' '

Teoricamente, ele seria impresso até PASSWORD, mas encontrei um erro completo no espaço de trabalho após o ZZZZ: o array 5-dimensional ser impressionante demais.

Edição: Deve ter sido muito tempo desde a última vez que brincou com APL. Como ouso perder a comparação de identidade ( ) !!!

Explicação

{...}: Declara uma função que ...
⎕A∘.,⍵: Leva o produto externo à concatenação (todas as combinações de um elemento do operando esquerdo concatenam com um elemento do operando direito, exatamente como o produto cartesiano) entre as 26 letras maiúsculas ( ⎕A) e o argumento ( )

{...}¨: E para cada elemento do conjunto resultante, conecte-o a uma função que ...
⍞←⍵: imprima
'PASSWORD '≡e compare com 'PASSWORD '
: Se a comparação retornar true ( 1), aborte o programa.
: Caso contrário, retorne a sequência impressa.

: Finalmente, a função externa se recupera.

(Então, você concederá um produto externo à concatenação entre o alfa 26 e o ​​26 alfa, que fornece todas as combinações de duas letras, e depois o produto externo concatenará entre as combinações de duas letras e o alfa 26, etc ... Até que você alcançar PASSWORD que aciona a interrupção)

' ': A faísca !! Isso inicia a função recursiva com o caractere de espaço.


2

Python 2 - 153 152 151 149 bytes

from itertools import*;R=range
for l in iter(chain(*[product(*((map(chr,R(65,91)),)*n))for n in R(1,9)]).next,tuple("passwore")):print ''.join(l)

Salvo um byte usando UPPERCASE e outro usando novas linhas em vez de espaços.


1

Golfscript 41

Por falta de 'z'+1 == 'aa'lógica, o Golfscript não pode vencer este.

168036262484,(;{27base{96+}%' '+.96?0<*}%
  • 168036262484, criar matriz de 0 a 168036262483
  • (; largar o 0
  • {.. }%itere sobre a matriz
  • 27base converter elemento para matriz base 27
  • {96+}% adicione 96 a cada dígito
  • ' '+ converter em string e adicionar um espaço até o final
  • .96?0<* truncar string para zero se contiver char 96

1

Em Ruby, 39 40.

a=&`
0x1e0c2443dc.times{$><<a.succ!+' '}

..ou 129052722140. (Edit: anteriormente eu tinha 129052722. Eu tinha perdido alguns dígitos cortando e colando. Hex anterior ( 0x7B13032) era para número incorreto.). Emprestado a=?`do @Doorknob para salvar um personagem.


Eu tentei corrigir a a=?` coisa, parece meio estranho e tem um espaço extra no final, mas pelo menos ele funciona: P
Doorknob

Então, de onde vem o número 129052722? Pelo meu cálculo, isso parece lhe dar o intervalo "a" a "kwkokg" ... um pouco pequeno.
embalagem de pão

@Breadbox Calculei esse número com o seguinte método (desculpe pela formatação, mas os comentários têm limitações, não é?): ORD_BASE_ASCII = 'a'.ord-1; def nbr(word); len = word.size; word.split('').inject(0) {|t,c| offset = c.ord - ORD_BASE_ASCII; t + offset*(26**(len -= 1))}; end É fácil confirmar que isso está correto, apenas imprimindo algumas seqüências.
Cary Swoveland

@breadbox Você estava certo. Veja editar. O método que eu dei no comentário está OK.
Cary Swoveland

Erros no poste. Seu script está calculando usando a = 1..z = 26. Você precisa calcular a = 0..z = 25 para obter a contagem certa. Ao remover o -1 da primeira linha, você obterá 120699639557, que (adicionando um para a entrada zeroth) corresponde ao meu cálculo.
embalagem de pão

1

Javascript: 57 56 caracteres (obrigado C5H8NNaO4)

Aqui está uma solução que inclui números como caracteres possíveis ("0", "1", "2", .., "passwor9", "passwora", "passworb", "passworc", "password")

for(i=-1;i++<1982613533017;console.log(i.toString(36)));

Aqui está um teste para testar (com apenas as últimas 100 iterações para não bloquear o navegador).


3
Esta solução está errada, não segue a especificação.
Maçaneta

@ Doorknob - Sim, eu mencionei isso na minha resposta. Ele ainda imprime todos os casos com base nos requisitos originais, mas também imprime todos os casos alfanuméricos.
precisa saber é o seguinte

Além disso, depois de reler a pergunta, se eu definir i para 9 no meu código, ele atenderá a todos os requisitos da pergunta, exceto pelo exemplo de saída, para o qual ele já deu uma exceção (e aumentaria o código para 56 caracteres )
precisa saber é o seguinte

@ Briguy37 A especificação diz print every **letter** combinationDe qualquer forma, salvar um personagem:{} -> ;
C5H8NNaO4

@ C5H8NNaO4: Que combinação de letras minha solução não imprime? Obrigado pela dica!
precisa saber é o seguinte

1

Haskell, 101

main=putStrLn.concat.takeWhile(/="passwore ").tail.concat.iterate(\k->[x:y|x<-['a'..'z'],y<-k])$[" "]

0

Befunge (72)

<_v#:/*2+67\+++88*99%*2+76:
^ >$>:#,_84*+,1+:0\:" Lr$W~"67++**1+***6+`#@_

Imprime as seqüências de caracteres 'a' em 'senha' separadas por espaços e sai.

Abaixo está uma versão que imprime apenas as primeiras 9 * 9 = 81 palavras ('a' a 'dd'), para comparação. O 99*é o número de iterações a serem executadas.

<_v#:/*2+67\+++88*99%*2+76:
^ >$>:#,_84*+,1+:0\:99*`#@_

0

JavaScript 80 76

for(i=s=0;s!="password";i++){s=i.toString(36).replace(/[0-9]/,'');console.log(s)}

violino - para em "pa".

no entanto, isso repete as coisas.


Você pode inicializar o loop com i=s=0para salvar mais três caracteres.
Ry-

@minitech done.
Math chiller

11
Por que manter o var? iera global antes; agora sé global. Você pode manter os dois globais no código de golfe, normalmente.
Ry- 25/09/13
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.