How to decode a Base64 string?

PowershellBase64

Powershell Problem Overview


I have a normal string in Powershell that is from a text file containing Base64 text; it is stored in $x. I am trying to decode it as such:

$z = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($x));

This works if $x was a Base64 string created in Powershell (but it's not). And this does not work on the $x Base64 string that came from a file, $z simply ends up as something like 䐲券.

What am I missing? For example, $x could be YmxhaGJsYWg= which is Base64 for blahblah.

In a nutshell, YmxhaGJsYWg= is in a text file then put into a string in this Powershell code and I try to decode it but end up with 䐲券 etc.

Powershell Solutions


Solution 1 - Powershell

Isn't encoding taking the text TO base64 and decoding taking base64 BACK to text? You seem be mixing them up here. When I decode using this online decoder I get:

BASE64: blahblah
UTF8: nVnV

not the other way around. I can't reproduce it completely in PS though. See sample below:

PS > [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("blahblah"))
nV�nV�

PS > [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nVnV"))
blZuVg==

EDIT I believe you're using the wrong encoder for your text. The encoded base64 string is encoded from UTF8(or ASCII) string.

PS > [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("YmxhaGJsYWg="))
blahblah

PS > [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String("YmxhaGJsYWg="))
汢桡汢桡

PS > [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String("YmxhaGJsYWg="))
blahblah

Solution 2 - Powershell

There are no PowerShell-native commands for Base64 conversion - yet (as of PowerShell [Core] 7.1), but adding dedicated cmdlets has been suggested in GitHub issue #8620.
For now, direct use of .NET is needed.

Important:

  • Base64 encoding is an encoding of binary data using bytes whose values are constrained to a well-defined 64-character subrange of the ASCII character set representing printable characters, devised at a time when sending arbitrary bytes was problematic, especially with the high bit set (byte values > 0x7f).

  • Therefore, you must always specify explicitly what character encoding the Base64 bytes do / should represent.

Ergo:

  • on converting TO Base64, you must first obtain a byte representation of the string you're trying to encode using the character encoding the consumer of the Base64 string expects.

  • on converting FROM Base64, you must interpret the resultant array of bytes as a string using the same encoding that was used to create the Base64 representation.

Examples:

Note:

  • The following examples convert to and from UTF-8 encoded strings:

  • To convert to and from UTF-16LE ("Unicode") instead, substitute [Text.Encoding]::Unicode for [Text.Encoding]::UTF8

Convert TO Base64:

PS> [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('Motörhead'))
TW90w7ZyaGVhZA==

Convert FROM Base64:

PS> [Text.Encoding]::Utf8.GetString([Convert]::FromBase64String('TW90w7ZyaGVhZA=='))
Motörhead

Solution 3 - Powershell

This page shows up when you google how to convert to base64, so for completeness:

$b  = [System.Text.Encoding]::UTF8.GetBytes("blahblah")
[System.Convert]::ToBase64String($b)

Solution 4 - Powershell

Base64 encoding converts three 8-bit bytes (0-255) into four 6-bit bytes (0-63 aka base64). Each of the four bytes indexes an ASCII string which represents the final output as four 8-bit ASCII characters. The indexed string is typically 'A-Za-z0-9+/' with '=' used as padding. This is why encoded data is 4/3 longer.

Base64 decoding is the inverse process. And as one would expect, the decoded data is 3/4 as long.

While base64 encoding can encode plain text, its real benefit is encoding non-printable characters which may be interpreted by transmitting systems as control characters.

I suggest the original poster render $z as bytes with each bit having meaning to the application. Rendering non-printable characters as text typically invokes Unicode which produces glyphs based on your system's localization.

Base64decode("the answer to life the universe and everything") = 00101010

Solution 5 - Powershell

I had issues with spaces showing in between my output and there was no answer online at all to fix this issue. I literally spend many hours trying to find a solution and found one from playing around with the code to the point that I almost did not even know what I typed in at the time that I got it to work. Here is my fix for the issue: [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($base64string)|?{$_}))

Solution 6 - Powershell

Still not a "built-in", but published to gallery, authored by MS:

https://github.com/powershell/textutility

TextUtility

  • ConvertFrom-Base64
    Return a string decoded from base64.
  • ConvertTo-Base64
    Return a base64 encoded representation of a string.

Solution 7 - Powershell

If anyone would like to do it with a pipe in Powershell (like a filter) (e.g. read file contents and decode it), it can be achieved with a one-liner like that:

Get-Content base64.txt | %{[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($_))}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJBuraceView Question on Stackoverflow
Solution 1 - PowershellFrode F.View Answer on Stackoverflow
Solution 2 - Powershellmklement0View Answer on Stackoverflow
Solution 3 - PowershellKERRView Answer on Stackoverflow
Solution 4 - PowershellcknoxView Answer on Stackoverflow
Solution 5 - Powershell中野春子View Answer on Stackoverflow
Solution 6 - PowershellyzorgView Answer on Stackoverflow
Solution 7 - Powershellandrew.foxView Answer on Stackoverflow