Representing a hash differs from re-encoding its text

A SHA-256 result is 256 bits, or 32 bytes. RFC 4648 Base16 represents each byte with two hexadecimal digits, giving 64 characters. Padded standard Base64 represents the same 32 bytes with 44 characters. Encoding the 64-character hexadecimal string as UTF-8 text instead uses 64 input bytes and produces 88 Base64 characters. That 88-character result encodes the text displaying the hash, rather than the raw hash bytes.

Raw hash bytes: 32 bytes to 44 Base64 characters; HEX text: 64 bytes to 88 Base64 characters
An original byte-flow diagram. A is the raw hash bytes; B is the 64-character HEX text. The Base64 counts 44 and 88 include padding.

RFC 6234: SHA-256 digest size

RFC 4648 §4, §8: Base64 / Base16

Check the input before using the tools

We hashed abc with SHA-256 and reproduced both paths in code. Moyoutil’s hash tool outputs hexadecimal text. Pasting that value into Moyoutil’s Base64 tool encodes the text’s UTF-8 bytes and produces 88 characters. This Base64 tool does not interpret HEX input as raw hash bytes. The separate Web Crypto example below distinguishes raw bytes from HEX text and prints the lengths for both paths.

const raw = new Uint8Array(await crypto.subtle.digest(
  'SHA-256', new TextEncoder().encode('abc')));
const hex = Array.from(raw,
  n => n.toString(16).padStart(2, '0')).join('');
const rawBase64 = btoa(String.fromCharCode(...raw));
const textBase64 = btoa(hex); // ASCII HEX text
console.log(raw.length, hex.length,
            rawBase64.length, textBase64.length);
// 32 64 44 88

Check the receiving system’s documentation for the required representation. Base64 versus Base64url, padding and the data being encoded are separate conditions. A matching string length does not establish a matching checksum. This article explains representation conversion; it does not provide signature verification or determine whether a file is safe.

Frequently Asked Questions

Does converting to Base64 calculate the hash again?

No. Encoding raw hash bytes changes their representation. Encoding HEX text uses different input data. Keep both operations separate from recalculating SHA-256 for the original data.