Skip to content

Conversation

@blurpiflurp
Copy link

Its a little bit shorter. 288>179

Its a little bit shorter. 288>179
@blurpiflurp
Copy link
Author

blurpiflurp commented Jun 4, 2019

Also if its allowed to use external apps in core linux/osx we can do
$p='P@ssw0rd';$p|Out-File -non p;$a,$b=(filehash -a SHA1 p).hash-split'(?<=^.{5})';(((irm "https://api.pwnedpasswords.com/range/$a")|grep $b)-split":")[1]

which results in 154 chars.

$p='P@ssw0rd';$p|Out-File -non p;$a,$b=(filehash -a SHA1 p).hash-split'(?<=^.{5})';((irm "https://api.pwnedpasswords.com/range/$a")-split"`n"-like"$b*").split(":")[1]
166 chars without going thru grep.

@JonasForsell
Copy link

JonasForsell commented Jun 5, 2019

Piping 'P@ssw0rd' saves a few characters, also using -match instead of -like saves a bit more. Quotation marks not needed for this call so two more in the bank.
'P@ssw0rd'|Out-File -non p;$a,$b=(filehash -a SHA1 p).hash-split '(?<=^.{5})';((irm https://api.pwnedpasswords.com/range/$a).split("n")-match $b).split(":")[1]`
Results in 160 chars

For non-core
[Net.ServicePointManager]::SecurityProtocol='Tls12';$p='P@ssw0rd';$a,$b=(FileHash -A SHA1 -I([IO.MemoryStream]::new([byte[]][char[]]$p))).Hash-split'(?<=^.{5})';((irm https://api.pwnedpasswords.com/range/$a|findstr $b)-split(":"))[1]

Best i can do for now. Will try to do better. Basicly the only saving right now is casting to bytearray and chararray.

EDIT:
Soo i tried avoiding declaring $a and $b by passing a formatted string to Invoke-Expression. Sadly the resulting code is a bit longer.

("[Net.ServicePointManager]::SecurityProtocol='Tls12';(irm https://api.pwnedpasswords.com/range/{0}|findstr {1})-split ':'" -f ((FileHash -A SHA1 -I([IO.MemoryStream]::new([byte[]][char[]]'P@ssw0rd'))).Hash-split'(?<=^.{5})')|iex)[1]

@DanielLettau
Copy link

Got it down to 155 chars not including line breaks but minding TLS12 and using PowerShell code only. TLS12 however only works in PowerShell 6 and 7

'P@ssw0rd'|out-file -non p
$a,$b=(FileHash -A SHA1 p).Hash -split '(?<=^.{5})'
(irm api.pwnedpasswords.com/range/$a -Ss Tls12)-match "$b.(.*)"|%{$matches[1]}

@blurpiflurp
Copy link
Author

blurpiflurp commented Jun 6, 2019

@DanielLettau nice use of the match.

So since you don't have to specify -Ss Tls12 in powershell 6/7 and you don't need whitespaces for split/match etc it can be a bit shorter. We're down to 142 without newlines.

'P@ssw0rd'|out-file -non p
$a,$b=(FileHash -A SHA1 p).Hash-split'(?<=^.{5})'
(irm api.pwnedpasswords.com/range/$a)-match"$b.(.*)"|%{$matches[1]}

If you don't mind a true being printed we get 138 without newlines
'P@ssw0rd'|out-file -non p
$a,$b=(FileHash -A SHA1 p).Hash-split'(?<=^.{5})'
(irm api.pwnedpasswords.com/range/$a)-match"$b.(.*)"
$matches[1]

@tpowelldev
Copy link

You can still get to 142 (with newlines) without printing a True, with the following bit of obfuscated trickery:

'P@ssw0rd'|Out-File -NoN a
$a,$b=(FileHash a SHA1|% h*)-split'(?<=^.{5})'
$c=(irm api.pwnedpasswords.com/range/$a)-match$b+':(.+)'
$Matches[1]

Or if you really want to shorten it (and you're too trusting):
iwr bit.ly/31d3nIz|iex

@DanielLettau
Copy link

@tpowelldev We can save one more char and remove the password from the filesystem
'P@ssw0rd'|Out-File -NoN a
$a,$b=(FileHash a SHA1|% h*)-split'(?<=^.{5})'
(irm api.pwnedpasswords.com/range/$a)-match$b+':(.+)'>a
$Matches[1]

@blurpiflurp
Copy link
Author

@tpowelldev iwr u.nu/xrl4|iex

@Keili78
Copy link

Keili78 commented Jun 6, 2019

a bit shorter using sc instead of out-file
'P@ssw0rd'|sc f -non;$a,$b=(FileHash -A SHA1 f).Hash -split '(?<=^.{5})';(irm api.pwnedpasswords.com/range/$a)-match $b+':(.*)';$matches[1]

@DanielLettau
Copy link

@Keili78 In case of sc we could reduce -non to -n. However then the script is then limited to PS5. But hey, 136 characters with ; or 133 with linebreaks (if you don't count the linebreaks)
'P@ssw0rd'|sc -N a;$a,$b=(FileHash a -a SHA1|% h*)-split'(?<=^.{5})';(irm api.pwnedpasswords.com/range/$a)-match$b+':(.+)'>a;$Matches[1]

@tpowelldev
Copy link

@DanielLettau I think there's 3 more chars you can drop by using the parameter order for Get-FileHash, so that gets us to 130, ignoring line breaks. (Full disclosure, I'm not in front of a PC to test currently)

'P@ssw0rd'|sc -N a;$a,$b=(FileHash a SHA1|% h*)-split'(?<=^.{5})';(irm api.pwnedpasswords.com/range/$a)-match$b+':(.+)'>a;$Matches[1]

@DanielLettau
Copy link

@tpowelldev that is true for ps version 6 and 7. In version 5 the positional parameters don't work for filehash. But in version 6 and 7 you can't use sc anymore. I guess they removed the alias sc due to a conflict with sc.exe

@tpowelldev
Copy link

'P@ssw0rd'|Out-File -NoN a
FileHash a SHA1|% h*|%{(irm api.pwnedpasswords.com/range/$($_|% Su* 0,5))-match"$($_|% Su* 5):(.+)"}>a
$Matches.1

While it's not quite 133, it's future forward so will work multi-platform with PS 6+. One less char from the last PS core (140), and a different route. Might give some more ideas...

@JonasForsell
Copy link

Now this is cheating but a bit out of the box thinking:

Install-Module haveibeenpwned;ipmo haveibeenpwned;PwnedPassword -P 'P@ssw0rd'

@DanielLettau
Copy link

Oh oh, we lost SSL support on the way. Guess it has to get in again since it was in the original code. I would go for this for the final solution. 145 chars.

'P@ssw0rd'|Out-File -NoN a
$a,$b=(FileHash a SHA1|% h*)-split'(?<=^.{5})'
(irm https://api.pwnedpasswords.com/range/$a)-match$b+':(.+)'>a
$Matches.1

@tpowelldev I get an error due to the blocked file "a" on Windows. Guess ">a" should be best cahnged to an unused filename (e.g. >b). I like how you still got out 1 more character from the Matches variable.

@bielawb
Copy link
Contributor

bielawb commented Jun 7, 2019

Just a note: Out-File gives wrong results on my box (Windows PowerShell 5.1, Windows 10):

FileHash -A SHA1 -I ([IO.MemoryStream]::new(([Text.Encoding]::UTF8|% G*es $p)))|% H*
$p|Out-File -NoN a;FileHash a -a SHA1|% h*
# Output:
21BD12DC183F740EE76F27B78EB39C8AD972A757
E4AC83ADD76654E3D339AAE72DBB364DC8380CC5

@JonasForsell
Copy link

Just a note: Out-File gives wrong results on my box (Windows PowerShell 5.1, Windows 10):

FileHash -A SHA1 -I ([IO.MemoryStream]::new(([Text.Encoding]::UTF8|% G*es $p)))|% H*
$p|Out-File -NoN a;FileHash a -a SHA1|% h*
# Output:
21BD12DC183F740EE76F27B78EB39C8AD972A757
E4AC83ADD76654E3D339AAE72DBB364DC8380CC5

This code only works in PowerShell Core unfortunately.

@eDISCO
Copy link

eDISCO commented Jun 7, 2019

@JonasForsell, I think by default on 5.1 PS uses UTF-16.

@JonasForsell
Copy link

@JonasForsell, I think by default on 5.1 PS uses UTF-16.

Doublechecked and it seems it does not i'm afraid
`PS C:\WINDOWS\system32> $PSSessionOption

MaximumConnectionRedirectionCount : 5
NoCompression : False
NoMachineProfile : False
ProxyAccessType : None
ProxyAuthentication : Negotiate
ProxyCredential :
SkipCACheck : False
SkipCNCheck : False
SkipRevocationCheck : False
OperationTimeout : 00:03:00
NoEncryption : False
UseUTF16 : False
IncludePortInSPN : False
OutputBufferingMode : None
MaxConnectionRetryCount : 5
Culture :
UICulture :
MaximumReceivedDataSizePerCommand :
MaximumReceivedObjectSize : 209715200
ApplicationArguments :
OpenTimeout : 00:03:00
CancelTimeout : 00:01:00
IdleTimeout : -00:00:00.0010000`

@blurpiflurp
Copy link
Author

'P@ssw0rd'|Out-File -NoN a -E ascii
$a,$b=(FileHash a -a SHA1|% h*)-split'(?<=^.{5})'
$a
21BD1
$b
2DC183F740EE76F27B78EB39C8AD972A757

@blurpiflurp
Copy link
Author

'P@ssw0rd'|Out-File a ascii -non
$a,$b=(FileHash a -a SHA1|% h*)-split'(?<=^.{5})'
(irm api.pwnedpasswords.com/range/$a)-match$b+':(.+)'>a
$Matches.1

So this works fine on Win10/1903 PowerShell 5.1 and also on OS X Core 6.2, 7.0.

@Redicious
Copy link

[Net.ServicePointManager]::SecurityProtocol='Tls12'
sc -v P@ssw0rd p -N;$a,$b=(FileHash p -A SHA1|% h*)-split'(?<=^.{5})';((irm api.pwnedpasswords.com/range/$a)-split"$b`:(\d+)")[1]

Hey guys, above you see one of the solutions I send to Tobias. As I wasn't quite sure which PowerShell version to pick... So I listed the 5.1 Windows edition first in my mail - as this is the most common version.
I also noted how the code could get shorter with newer PSVersions and how it would look like on Core.

In PS 5 the Tls-thingy is really expensive, on 6 you can of course set it via parameter, where core on ubuntu doesn't care at all, and is therefore the shortest - although there is no alias for set-content.

All those techniques were already presented in "The PowerShell Playbook" by Bartosz Bielawski on Thursday.
https://github.com/psconfeu/2019/tree/master/sessions/Bartosz%20Bielawski/The%20PowerShell%20Playbook
Also this is a quite good source:
https://codegolf.stackexchange.com/questions/191/tips-for-golfing-in-powershell

-split"$b`:(\d+)")[1]

this part saves a lot chars, and I haven't seen it here before - so I want to explain it shortly.
Using -match is the cleaner approach, but we don't want it clean - it should be short. So I abuse -split here and mark the count we want to extract with parenthesis. This tells split to keep this part of the delimiter and add it as a separate element to the array, which is in this case at location [1].
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_split?view=powershell-6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants