Base64url Encode
Base64url encode text the way a JSON Web Token does: the URL-safe alphabet with - and _, and no padding. It opens on a JWT header, which comes out as the familiar eyJ prefix.
Base64url
- Length Unpadded: ceil(27 x 4 / 3) = 36. Padded it would be 36.
- 36 characters
- Bytes encoded From 27 characters, all ASCII, so one byte each.
- 27 bytes of UTF-8
- Padding 27 is a multiple of 3, so the last group is full and nothing is added.
- none needed
- Size increase
- 33%
- Alphabet RFC 4648 section 5. The same as standard Base64 except that values 62 and 63 are written - and _, which need no escaping in a URL or a file name.
- URL-safe, - and _
| Group | Bytes (hex) | Six-bit groups | Indexes | Base64 |
|---|---|---|---|---|
| 1 | 7B 22 61 | 011110 110010 001001 100001 | 30, 50, 9, 33 | eyJh |
| 2 | 6C 67 22 | 011011 000110 011100 100010 | 27, 6, 28, 34 | bGci |
| 3 | 3A 22 48 | 001110 100010 001001 001000 | 14, 34, 9, 8 | OiJI |
| 4 | 53 32 35 | 010100 110011 001000 110101 | 20, 51, 8, 53 | UzI1 |
| 5 | 36 22 2C | 001101 100010 001000 101100 | 13, 34, 8, 44 | NiIs |
| 6 | 22 74 79 | 001000 100111 010001 111001 | 8, 39, 17, 57 | InR5 |
How the Base64 Decode and Encode works
Base64url is standard Base64 with two characters changed. Values 62 and 63 are + and / in the standard alphabet, and both mean something in a URL: + can be read as a space in a query string and / separates path segments. RFC 4648 section 5 defines the URL- and filename-safe alphabet, which writes them as - and _ instead. Every other character, and every bit of the method, is the same.
The padding usually goes as well. The = sign is also special in a URL (it separates a query key from its value), and padding carries no data: the length of the string already says how many bytes the last group holds. Two leftover characters mean one byte and three mean two. So base64url is normally written without it, and JSON Web Tokens (RFC 7519) require that.
The example is the JWT header {"alg":"HS256","typ":"JWT"}, 27 bytes of ASCII. 27 is a multiple of three, so it encodes to exactly 36 characters with no padding to drop, and it starts eyJ because every JSON object starts with {", which encodes to eyJ. That is why a token is recognizable at a glance. The header holds no + or / either, so for this input the URL-safe and standard alphabets agree. Other text differs wherever the bits make a 62 or a 63.
Decoding base64url needs no setting. The Base64 decoder reads either alphabet and works out the padding from the length, so a JWT segment pasted as is decodes to its JSON. It does refuse a string that mixes the two alphabets, which usually means two values were pasted together.
A JWT's payload is readable by anyone who has the token, since base64url is an encoding and not encryption. The signature proves the token was not changed; it does not keep the claims secret.
Base64 Decode and Encode FAQ
What is the difference between Base64 and Base64url?
Two characters and the padding. Base64url writes values 62 and 63 as - and _ instead of + and /, so the result is safe in URLs and file names, and it usually leaves off the trailing = signs. The decoded bytes are identical.
Why do JWTs start with eyJ?
Because the header is a JSON object, which starts with {" and those two bytes, 7B 22, plus the high bits of the next byte, encode to eyJ. The payload is JSON too, so the second segment usually starts with eyJ as well.
How do I convert base64url back to standard Base64?
Replace - with + and _ with /, then add = until the length is a multiple of four. A decoder that reads base64url directly does not need the padding.