Search code examples
algorithmperlgnupg

Brute force my gpg password


Stupidly, I've forgotten my gpg password.

I know the password is made up of three of six strings connected by a "_".

The possibilites are (let's say) "1", "2", "3", "4", "5" and "6".

Let's say the password is actually "2_5_3".

How to loop through all combinations? There should be no duplicates (i.e. "2_2_4" is not a valid password)!

I'm trying to write this in Perl, but don't really know where to start. Pseudo-code is good.

Many thanks in advance,

UPDATE: OK, I got it working now.

Not as elegant as some of the solutions below...

#!/usr/bin/perl

use strict;
use warnings;

my @possibilities=("111","222","333","444","555","666","777");

my $size=scalar(@possibilities);
print $size."\n";

for(my $i=0;$i<$size;$i++){
        for(my $j=0;$j<$size;$j++){
                for(my $k=0;$k<$size;$k++){
                        if($i==$j || $j==$k || $i==$k){

                        }else{
                                print $i."_".$j."_".$k."\n";
                        }
                }
        }
}

Solution

  • Basically you need three for loops to iterate over each word (or a multi-index). Since you want to ensure that there aren't any duplicates you have to skip those (Python code):

    names = ["abc","def","ghi","jkl","mno","pqr"]
    
    for x in names:
        for y in names:
            if y in [x]: # word already used?
                continue # skip duplicates
            for z in names:
                if z in [x,y]: # word already used?
                    continue   # skip duplicates
                print(x+"_"+y+"_"+z)
    

    UPDATE: Perl code (the very first I've ever written, so I guess it's gross for the Perl developer's eye...)

    use strict;
    use warnings;
    
    my @words = ("abc","def","ghi","jkl","mno","pqr");
    foreach my $w1 (@words){
        foreach my $w2(@words){
            next if $w1 eq $w2;
            foreach my $w3(@words){
            next if $w3 eq $w1;
            next if $w3 eq $w2;
                print $w1.'_'.$w2.'_'.$w3."\n";
            }
        }
    }