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.