24
\$\begingroup\$

Help! I just logged into Stack Exchange, but I forgot what my password is! I need a way to work it out before I log off.

Luckily, I'm an excellent hacker. Not only was I able to find my password's hash, but I also found Stack Exchange's hashing algorithm! It takes the ASCII value of each digit multiplied by that digit's place, then sums all those values together. For example:

"135" -> 1*49 + 2*51 + 3*53 = 310

I remember that my password is 3 digits long, and that each character is a number between 0 and 5 inclusive (such that it will match the regex: ^[0-5]{3}$), but that's still too many possibilities to guess. I need a program that can convert a hash back into potential passwords, but despite being an expert hacker, I can't code to save my life! I was able to write these tests out by hand though:

input -> output
288   -> 000                      // lowest possible hash
290   -> 200, 010
298   -> 022, 050, 103, 131, 212, 240, 321, 402, 430, 511   
318   -> 555                      // highest possible hash

Can one of you write a program for me that will take in a hash and print all the possible passwords I could have used?

The input will always be able to produce at least one valid password. Any output format is allowed, as long as the strings can be clearly identified. I'm also not concerned about leading zeroes, so if a potential password is 001, I'll also accept 01 or 1.

Please help me from being locked out of Stack Exchange!

Scoring

This is , so the shortest answer in each language wins!

\$\endgroup\$
  • \$\begingroup\$ Isn't 1's Ascii value 49 instead of 48? \$\endgroup\$ – LiefdeWen Jul 17 '17 at 14:20
  • 1
    \$\begingroup\$ @LordFarquaad test cases look fine but example should be "135" -> 1*49 + 2*51 + 3*53 = 310 \$\endgroup\$ – LiefdeWen Jul 17 '17 at 14:24
  • 1
    \$\begingroup\$ must be delimited by a comma (a comma followed by one or more spaces is ok too) Why the restrictive output format? We usualy allow flexible formats \$\endgroup\$ – Luis Mendo Jul 17 '17 at 14:41
  • 1
    \$\begingroup\$ The usual here is to say something like "any ouput format is allowed, as long as the strings can be clearly identified". Or maybe allow any non-numeric separator. If you change it, notify current answerers with a comment in their answer \$\endgroup\$ – Luis Mendo Jul 17 '17 at 14:45
  • 1
    \$\begingroup\$ @FelipeNardiBatista Yep, leading zeroes are optional. I remember I used 3 digits, so if I just see 54 I can work out the zeroes in front. \$\endgroup\$ – Lord Farquaad Jul 17 '17 at 14:56

15 Answers 15

10
\$\begingroup\$

05AB1E, 9 bytes

5Ý3ãʒÇƶOQ

Try it online!

Returns list of lists of digits.

\$\endgroup\$
  • 3
    \$\begingroup\$ That makes for a pretty decent password. \$\endgroup\$ – Veedrac Jul 19 '17 at 1:44
9
\$\begingroup\$

C, 113 108 bytes

f(int h){int i=47,j,k;while(++i<54)for(j=47;++j<54)for(k=47;++k<54;)if(h==i+j+j+k*3)printf("%c%c%c",i,j,k);}

It is unique to see what is meant for output, the output is of the format: 200010

All passwords are written as 3-digits without delimiter.

\$\endgroup\$
  • 2
    \$\begingroup\$ Hey, code I can read! Nice contrast to Jelly and such. +1 for using a classic language. :) \$\endgroup\$ – Wildcard Jul 17 '17 at 19:58
8
\$\begingroup\$

Jelly, 16 bytes

Ṿ€Oæ.J
6Ḷṗ3Ç⁼¥Ðf

A monadic link returning a list of lists of digits.

Try it online!

How?

Ṿ€Oæ.J - Link 1, hash: list of integers (the digits of a password)
Ṿ€     - unevaluate €ach (giving a list of characters)
  O    - cast to ordinals (Ṿ€O could actually be replaced with +48 too)
     J - range of length (i.e. [1,2,3] in all use-cases)
   æ.  - dot product

6Ḷṗ3Ç⁼¥Ðf - Main link: number, n
6Ḷ        - lowered range of 6 = [0,1,2,3,4,5]
  ṗ3      - Cartesian power with 3 = [[0,0,0],[0,0,1],...,[5,5,5]] (all passwords)
       Ðf - filter keep if:
      ¥   -   last two links as a dyad (right implicitly n):
    Ç     -     call last link (1) as a monad
     ⁼    -     equals right?
\$\endgroup\$
5
\$\begingroup\$

Python 2, 126 75 bytes

-2 thanks to @ArnoldPalmer

lambda h:[(P/36,P%36/6,P%6)for P in range(216)if P/36+P%36/6*2+P%6*3==h&31]

Try it online!

\$\endgroup\$
4
\$\begingroup\$

MATL, 20 bytes

'0':'5'3Z^t3:*!si=Y)

Try it online!

Explanation

'0':'5'   % Push inclusive range from '0' to '5', that is, '012345'
3Z^       % Cartesian power with exponent 3. Each Cartesian tuple is a row
t         % Duplicate
3:        % Push [1 2 3]
*         % Multiply element-wise with broadcast
!s        % Sum of each row
i         % Input number
=         % Logical mask of values that equal the input
Y)        % Use as logical index into the rows of the matrix. Implicit display
\$\endgroup\$
3
\$\begingroup\$

Python 2, 81 bytes

lambda h:[(a,b,c)for a in r for b in r for c in r if a+2*b+3*c+288==h]
r=range(6)

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Haskell, 71 70 64 61 bytes

l=[0..5]
f p=[show=<<[a,b,c]|a<-l,b<-l,c<-l,p-288==a+2*b+3*c]

Try it online!

\$\endgroup\$
2
\$\begingroup\$

C# (.NET Core),133 131 125 123 bytes

n=>{int i,j,k;for(i=48;i<54;++i)for(j=48;j<54;++j)for(k=48;k<54;++k)if(i+j*2+k*3==n)Console.Write($"{i%48}{j%48}{k%48},");}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I gave more thorough advice previously, but I didn't get it to work right. For now my simple optimization is to use Console.Write($"{i%48}{j%48}{k%48},"); for output rather than building a return value, and removing the unnecessary brackets around the if statement to save 8 bytes. \$\endgroup\$ – Kamil Drakari Jul 17 '17 at 16:53
  • \$\begingroup\$ I tried that option previously, but the Lambda requires a return value. Removing the brackets will work though. Thanks :) \$\endgroup\$ – jkelm Jul 17 '17 at 17:47
  • \$\begingroup\$ The lambda requires a return value if you define it as Func<int,string>, but if you define it as Action<int> then it doesn't expect a return value. \$\endgroup\$ – Kamil Drakari Jul 17 '17 at 17:49
  • \$\begingroup\$ Did not realize that! I am new to both c# and golfing, but decided to try it out when I have nothing else to do at work. Thanks again for the tips. I greatly appreaciate them. \$\endgroup\$ – jkelm Jul 17 '17 at 17:51
  • 1
    \$\begingroup\$ If you play with the ambiguity between char and int in C#, you can declare your iteration variables as char in the first loop and still do the hash calculation exactly as you do while simplifying the Console.Write() sentence. Thus you can get a proper 119-byte solution. Try it online! \$\endgroup\$ – Charlie Jul 18 '17 at 11:04
2
\$\begingroup\$

Charcoal, 33 bytes

F⁶F⁶F⁶¿⁼⁺℅Iι⁺×℅Iκ²×℅Iλ³Iθ«IιIκIλ⸿

Try it online!

A similar approach to other answers: loop thrice from 0 to 5, calculate the hash and print the state of the iteration variables if it coincides with the input hash.

Link to the verbose version.

\$\endgroup\$
2
\$\begingroup\$

CJam, 26 25 bytes

-1 byte thanks to Challenger5

{:H;6Zm*{s:i3,:).*:+H=},}

Anonymous block expecting the hash on the stack (as an integer) and leaves the result on the stack (as a list of strings).

Try it online!

Explanation

:H;    e# Store the hash in H.
6Zm*   e# 3rd Cartesian power of [0 1 2 3 4 5].
{      e# For each tuple in the power:
 s     e#  Stringify the tuple.
 :i    e#  Get the code point of each digit.
 3,:)  e#  Push [1 2 3].
 .*    e#  Element-wise multiplication of the two lists.
 :+    e#  Sum the result.
 H=    e#  Check if it's equal to the hash.
},     e# Filter the tuples to only ones for which this block gave a truthy result.
\$\endgroup\$
  • \$\begingroup\$ @LordFarquaad Oh, uh... I didn't even see that in the first place so I guess that's fortunate \$\endgroup\$ – Business Cat Jul 17 '17 at 14:50
  • \$\begingroup\$ {:H;6Zm*{s:i3,:).*:+H=},} is 1 byte shorter. It uses digit strings in the filter rather than numbers as to use m*'s automatic range. \$\endgroup\$ – Esolanging Fruit Jul 18 '17 at 8:01
  • \$\begingroup\$ @Challenger5 Nice, thanks! \$\endgroup\$ – Business Cat Jul 18 '17 at 12:49
2
\$\begingroup\$

Java, 162 Bytes

static void f(int n){for(int i=48;i<54;i++){for(int j=48;j<54;j++){for(int k=48;k<54;k++){if(i+j*2+k*3==n)System.out.println((char)i+""+(char)j+""+(char)k);}}}}
\$\endgroup\$
2
\$\begingroup\$

JavaScript (Firefox 30-57), 72 bytes

n=>[for(i of s="012345")for(j of s)for(k of s)if(n-i-j*2-k*3==288)i+j+k]
\$\endgroup\$
1
\$\begingroup\$

Pyth, 18 bytes

fqQs*VS3CMT^jkU6 3
\$\endgroup\$
1
\$\begingroup\$

QBIC, 40 bytes

[0,5|[0,5|[0,5|~a+b+b+c+c+c+288=:\?a,b,c

Explanation

[0,5|                Make a FOR loop run through the possible digits for pos 1, called a
[0,5|                Loop for #2, b
[0,5|                Loop for #3, c
                     Calculate the hash by taking a once, b twice and c thrice, 
                     and raising all to their ASCII codepoints
 a+b+b+c+c+c+288       
~               =:   IF thta is euqal to the given hash (read from cmd line)
\?a,b,c              THEN print the digits
                     (the IF and the FOR loops are auto-closed by QBIC)
\$\endgroup\$
1
\$\begingroup\$

R, 67 62 61 bytes

-5 bytes thanks to Jarko Dubbeldam

b=t(t(expand.grid(rep(list(0:5),3))));b[b%*%1:3==scan()-288,]

Try it online!

reads the number from stdin; returns a matrix where the rows are the characters.

It generates all possible trios of digits in a matrix format (b), computes the matrix product b * [1,2,3], takes the rows of b which match (subtracting 288 from the input which is 1*48+2*28+3*48) and returns them.

\$\endgroup\$
  • 1
    \$\begingroup\$ t(t(m)) is a shorthand for as.matrix(m) \$\endgroup\$ – JAD Jul 18 '17 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.