$ echo -n "apfjxkic-omyuobwd339805ak:60a06cd2ddfad610b9490d359d605407" | base64

The output has a return before Nw==. What is the correct way to generate base64 in Linux?

terminal screenshot

  • 5
    Are you certain the output contains a newline, and it's not just your window wrapping? That command worked fine for me on mac. What OS are you using? – Ian Jul 3 '17 at 5:10
  • 46
    RFC 2045, which defined Base64, REQUIRES a newline after 76 characters (max). What makes you think your example is not the correct way? – MSalters Jul 3 '17 at 8:40
  • 24
    @MSalters RFC 4648 specifically addresses that issue. Implementations MUST NOT add line feeds to base-encoded data unless the specification referring to this document explicitly directs base encoders to add line feeds after a specific number of characters. => this implementation is incorrect according to RFC 4648, as long as it claims to produce 'plain' base64-encoded output. More interestingly, GNU base64 (in question?) manpages specifically refers to RFC 3548, which also specifies no wrapping by default, and which RFC 4648 obsoletes. – Bob Jul 3 '17 at 10:46
  • 4
    @Bob: RFC's have a bit less respect for API stability; a base64 tool can't just change its output format without breaking scripts. – MSalters Jul 4 '17 at 6:44
  • 2
    @MSalters I cannot be certain an older version does not exist, but GNU base64 was written in 2004 and AFAICT always claimed to follow RFC 3548. RFC 3548 contains the same "MUST NOT add line feeds" clause. So even the original implementation was "wrong". At the very least, its implementation does not match its documentation. Anyway, you asked for why OP's example is correct and referenced an RFC; my response is the correct RFC that actually defines base64 in isolation. If your answer is "for historical reasons", so be it, but OP isn't wrong here. – Bob Jul 4 '17 at 7:05


echo -n "apfjxkic-omyuobwd339805ak:60a06cd2ddfad610b9490d359d605407" | base64 -w 0

From man base64:

-w, --wrap=COLS
Wrap encoded lines after COLS character (default 76). Use 0 to disable line wrapping.

  • 17
    Oh man, I always just piped this through tr. Good to know there's a "proper way". – Score_Under Jul 3 '17 at 17:05
  • The explanation about why the default value is not zero is a mistery for me. – Dherik Jul 25 at 21:01
  • 1
    @Dherik I guess it's courtesy towards text processing tools. base64 encodes arbitrary binary data as text. Tools that expect text usually read one line at a time and may not deal with very long lines well. If -w 0 was the default, you would get by default just one line of text; an enormously long line if the input was large. It's better to wrap by default. I think 76 was chosen because it's little less than 80 which is a sort of de-facto standard for terminals. – Kamil Maciorowski Jul 25 at 21:32
  • @KamilMaciorowski thank you for the information. Every time that I used the base64 command I needed to pass the -w 0 (and when I forgot, weird things can happen...), so this default behaviour was very strange to me. – Dherik Jul 25 at 21:35

This is inferior to Kamil's answer on systems which support the -w option to base64, but for cases when that is not available (e.g. Alpine Linux, an Arch Linux initramfs hook, etc.), you can manually process the output of base64:

base64 some_file.txt | tr -d \\n

This is the brute-force approach; instead of getting the program to co-operate, I am using tr to indiscriminately strip every newline on stdout.

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.