Base64 ⇄ Hex
Convert between Base64 and hexadecimal byte representations.
This tool runs entirely in your browser. Your data is never uploaded, never stored, and never leaves your device.
This converter carries the same bytes between Base64 and spaced hexadecimal pairs in either direction, so a key, digest or packet dump can be read in whichever notation the tool in front of you expects. It is a re-spelling rather than an encoding: four Base64 characters and six hex digits describe the same three bytes.
How to use it
- 1Pick a direction: Base64 → Hex, or Hex → Base64.
- 2Paste the string into the input box; the output appears underneath as you type.
- 3Copy the converted bytes from the output box. Switching direction leaves the input where it is and re-reads it as the other notation, so a string that converted cleanly one way usually errors the other — clear the box or paste the output back in yourself.
Example
- Input
- SGVsbG8h
- Output
- 48 65 6c 6c 6f 21
Hex comes out lowercase and space-separated. Fed back in, it also tolerates commas and 0x prefixes, so a byte array copied from a debugger works as-is — but an odd number of digits is rejected rather than quietly padded with a zero. Going the other way, two kinds of slack in Base64 are treated very differently. Padding and whitespace are forgiven: 3q2+7w and 3q2+7w== both give de ad be ef, and line breaks are stripped, so a PEM body pasted across several lines converts in one go. The URL-safe alphabet is not — a JWT segment, or any string carrying a hyphen or underscore, fails outright, because those stand in for + and / and have to be swapped back first.
What happens to your data
Both directions go through the browser's own atob and btoa, the same two functions your code would call; on the way into btoa the bytes are turned back into a string 32 KB at a time, so a long input never trips the argument limit. Failures are diagnosed here too: bad input leaves one red line and no output box at all, so a malformed key is identified without being transmitted to anything that could keep it. The string lives in a single component state variable and a reload empties it; nothing is written to storage and nothing is sent.
Last updated August 2026
A fingerprint comes out of openssl as colon-separated hex, the config file you are pasting it into wants Base64, and both strings describe the same thirty-two bytes in different handwriting. That is what brings most people here — a key, an initialisation vector, a digest, bytes off a packet capture — written one way by the tool that produced it and demanded the other way by the tool that reads it.
Work out first whether you are moving bytes or a number, because hexadecimal does both jobs. As a number, hex ff is 255, leading zeros mean nothing and the three digits of 0xfff are ordinary. As a byte string — a key, a hash, a hexdump — ff is one byte, 00ff is two, and an odd count means something was lost in the copy. Base64 only ever describes bytes, so a hex colour or a value off a calculator belongs in a base converter instead.
Neither notation records what the bytes are: no type, no length, no character set. Conversion is a shape check and nothing more. A four-letter English word is legal Base64 and turns into three meaningless bytes without a murmur, and a key that lost its last line converts as cleanly as a whole one. Acceptance means the input was well formed, never that it was the right value.
Hexadecimal also arrives dressed up. Fingerprints are colon-separated, MAC addresses use colons or hyphens, GUIDs use dashes. Spaces, commas and 0x prefixes are handled here; colons and hyphens are not and fail the digit check, so strip them first.
How it works
Toolvore moves everything through an intermediate array of bytes rather than translating characters directly, which is why the two directions are exact inverses. Base64 arrives in groups of four characters carrying six bits each, comes apart into three bytes, and every byte is printed as two lowercase hexadecimal digits separated by spaces. Hex goes back the other way: digits are read off in pairs into bytes, then bundled three at a time into four characters. The bytes survive and nothing else does, so hex comes out lowercase and spaced whatever you fed in, and a tool wanting one continuous run needs you to reshape it. Diagnosis is coarse: one line of error text, no output box and no position for the offending character, so a mistyped digit in a long run means bisecting the string yourself. And since a byte array has no expected length, nothing here can tell a complete value from a truncated one.
Common use cases
- Converting an openssl fingerprint into Base64 for a config file
- Reading a Base64 key as hex pairs to count its bytes
- Comparing a hex digest against a Base64 one from an API
- Preparing an initialisation vector in the notation a library expects
- Converting a byte array pasted from a hexdump
- Checking whether two credentials are the same bytes
Frequently asked questions
What is the difference between Base64 and hex?+
Both re-spell bytes as printable characters, trading size against readability. Hex uses sixteen characters, four bits each, exactly two per byte, so the text is twice the length of the data and any byte can be found by counting — which is why dumps, digests and fingerprints are written that way. Base64 uses sixty-four characters at six bits each, packing three bytes into four, so it grows by about a third and suits values travelling in headers and config files. Hex is case-insensitive; Base64 is not, and changing the case changes the bytes.
How do I convert a fingerprint or MAC address that has colons in it?+
Those separators are a display convention rather than part of the value, so removing them changes nothing. Openssl prints certificate fingerprints as colon-separated pairs, network gear writes MAC addresses with colons or hyphens, and a GUID carries dashes at fixed positions. Here, whitespace, commas and 0x prefixes are removed for you, but colons and hyphens are not, so a fingerprint pasted straight in fails the digit check and errors instead of converting. Do a find and replace on the separator first. Case does not matter going in, though what comes back is always lowercase.
Does an odd number of hex digits mean my data is corrupt?+
For a byte string, usually yes. Two hex digits make one byte, so a real byte string always has an even count, and an odd one means a character was dropped in a copy or a leading zero was trimmed by something treating the value as a number. That is why odd input is rejected here rather than quietly padded: guessing which end the missing digit belonged to is a coin flip, and prefixing a zero hands you the wrong bytes with no warning. Numbers are the exception: 0xfff is a legitimate three-digit number.
Why does Base64 end in equals signs, and can I drop them?+
Base64 works three bytes at a time. When the data does not divide by three, the last group is padded with equals signs so the text still comes in blocks of four — one leftover byte gives two, two leftovers give one, an exact multiple of three gives none. The padding carries no data; it tells a stream decoder where a value stopped. Some decoders insist on it, others accept a bare string, and formats built for URLs generally drop it. Do not add equals signs to a string already a multiple of four.
Why will a JWT segment or a token from a URL not convert?+
Because it is almost certainly base64url, a variant that swaps the two awkward characters: minus in place of plus, underscore in place of slash, so the value survives a query string or a filename. The standard alphabet gives those characters no meaning, so a decoder refuses the string rather than guessing. Replace every minus with a plus and every underscore with a slash and it converts normally. A whole JWT needs a step before that: it is three separately encoded segments joined by full stops, so convert one segment at a time.
Is it safe to paste a private key or a secret into a converter?+
The work here happens in code running in the page — the browser's own atob and btoa plus arithmetic over a byte array — with no upload in the component, nothing written to storage, and a single piece of component state that a reload empties. The string does not leave your machine by this route. That leaves the ordinary risks of any machine: clipboard history, an extension with permission to read pages, sync, screen sharing, someone behind you. For a production private key those are reason enough to use a local command instead.
How do I do the same conversion at a command line?+
These are general facts about the usual tools rather than anything about this page. xxd -p prints a file as continuous hex and xxd -r -p reads it back to bytes, so hex to Base64 is xxd -r -p piped into base64, and Base64 to hex is base64 -d piped into xxd -p. The decode flag differs by platform — GNU coreutils takes -d, the macOS build wants -D — while openssl base64 -d works on both. In Python, bytes.fromhex handles the hex side and base64.b64encode the other. Watch for a trailing newline from echo.
My Base64 converted fine but the bytes look wrong — what happened?+
Valid is not correct, and there are two usual culprits. The first is truncation: a shortened string of legal length decodes without complaint, so check the byte count against what the algorithm expects — 16 bytes for an AES-128 key, a UUID or an AES-CBC initialisation vector, 32 for AES-256 or a SHA-256 digest. The second is double encoding, where whatever produced the value encoded the hex text of the bytes rather than the bytes. It shows as twice the expected length, every byte in the ranges 30-39, 41-46 and 61-66.
Related tools
Base64 Encode/Decode
Encode text to Base64 or decode Base64 back to text.
UUID Generator
Generate one or many random UUID v4 identifiers.
Password Generator
Generate strong, random passwords with custom rules.
Morse Code Translator
Convert text to Morse code and back, with audio playback.