Binary, Hex and Full-Width Characters: A Practical Guide

2026-10-157 min readEncoding6 tools covered

Two small text problems cause a surprising number of bugs: a number in the wrong base, and a full-width character hiding inside a string that looks perfectly normal. Both are easy to detect once you know what to look for.

Key takeaways
  • Bases that are powers of two convert by grouping bits - 4 binary digits make 1 hex digit and 3 make 1 octal digit, so no division is needed
  • Each hex digit maps to exactly 4 bits, so 0xFF is 255 and 0x10 is 16 - missing or wrong prefixes change the value completely
  • Full-width digits and letters are different code points from the ASCII ones, so a password typed in full-width mode can never match
  • A full-width space is U+3000, not U+0020, and languages disagree about whether trim() removes it
  • Every full-width letter or digit sits exactly 0xFEE0 above its half-width counterpart: full-width A is U+FF21, ASCII A is U+0041
  • Both the base converter and the full-width converter run entirely in your browser, so nothing you type is uploaded

#When each number base shows up

Hex represents bytes, octal shows up in file permissions, and binary is the basis of bitwise work - each base has a fixed job rather than being interchangeable.

The value 255 written in all four bases, with where you actually meet it:

BaseWritten asWhere you see it
Binary (2)0b11111111Bitwise flags, permission masks
Octal (8)0o377Unix file modes, chmod 755
Decimal (10)255Application fields, everyday numbers
Hexadecimal (16)0xFFBytes, memory addresses, colour values, hashes

Type a value into the Base Converter and pick its current base; all four representations update live, including negatives, fractions and integers larger than 2^53.

The prefixes are what people get wrong. 0x means hex, 0b means binary and 0o means octal, so 10 and 0x10 differ by a factor of six.

#How to convert between bases

Bases that are powers of two convert by grouping bits, with no division required. This is the fastest way to convert by hand, and the one most often done backwards.

#Binary and hex: four bits per digit

One hex digit equals exactly 4 binary digits, so group from the right in fours and read each group:

binary   1011 1111 0000 1101
grouped  B    F    0    D
result   0xBF0D

Going the other way is easier still: expand each hex character into a fixed 4-bit group, padding the leftmost group with zeros if needed.

#Binary and octal: three bits per digit

One octal digit equals 3 binary digits, so the group width is 3 rather than 4:

binary   111 101 010
grouped  7   5   2
result   0o752
Warning

Always group from the right. Grouping from the left breaks whenever the bit count is not a multiple of 3 or 4 - 1011 split as 101|1 gives a wrong answer.

#Fractions need their own method

Fractional parts use repeated multiplication, which runs in the opposite direction from the division used for the integer part. Convert the two halves separately, then join them.

0.625 * 2 = 1.25   take 1
0.25  * 2 = 0.5    take 0
0.5   * 2 = 1.0    take 1
result: 0.101

A decimal like 0.1 has no finite binary representation, so the conversion always loses a little precision. That is the same reason 0.1 + 0.2 does not equal 0.3 in most languages.

#Why full-width characters break software

Full-width and half-width characters are different characters, and software does not treat them as equivalent - which is why a password that looks right can still be wrong.

  • Full-width digit 1 is U+FF11; ASCII 1 is U+0031
  • Full-width letter A is U+FF21; ASCII A is U+0041
  • Full-width space   is U+3000; ASCII space is U+0020
  • Full-width underscore _ is U+FF3F; ASCII _ is U+005F

They may look only slightly wider on screen, but string comparison, hashing and unique database indexes all see two different values. The user sees "my password is correct"; the program sees "no match".

Key point

Chinese IMEs in punctuation mode also convert digits, letters and underscores to full-width. This is the single most common cause of failed logins, and no validator reports a format error - you only see "incorrect username or password", which sends you looking in the wrong place.

#Finding the full-width character in your text

Check the character and byte counts first, then compare code points - doing it the other way round wastes a lot of time.

SymptomCauseWhat to use
Login fails but the password looks identicalA digit or letter is full-widthFull/Half Width
Form rejects input as containing illegal charactersA full-width space U+3000Text Counter for the byte count
JSON contains escapes such as \uff11A full-width character was serialisedUnicode Converter
Duplicate rows still insert despite a unique indexFull-width and half-width treated as two recordsFull/Half Width

A reliable order of work:

  1. Copy the failing string and compare its character and byte counts against what you expect
  2. Compare it against a string you know is correct to isolate the odd character
  3. Run it through Full/Half Width and compare again
  4. Update the stored value or password only after the fix is confirmed - do not relax the validation instead
Tip

The full-width converter leaves CJK characters and Chinese punctuation alone and only touches letters, digits, punctuation and spaces, so converting a whole Chinese paragraph is safe.

#Other uses for full-width conversion

Beyond fixing logins, full-width conversion is a data-cleaning step: normalise text before storing, comparing or searching it.

The three situations where it matters most:

  • Text copied out of Excel, PDFs or chat apps often has full-width digits and brackets
  • Chinese typography rules want half-width digits and letters but full-width sentence punctuation
  • Search backends need normalised input, or "ABC" and "ABC" return different result sets

Watch the length change: one full-width character takes 3 bytes in UTF-8, and its half-width form takes 1. If the target column has a length limit, re-check it after converting.

Note

The converter only changes code points. It does not convert between simplified and traditional Chinese, and it does not change letter case.

#Which tool for which job

What you needToolNotes
Convert across base 2, 8, 10 and 16Base ConverterEnter one value, all four bases update
Turn full-width letters and digits into half-widthFull/Half WidthCJK characters and punctuation stay as they are
Count characters versus bytesText CounterA mismatch reveals hidden characters
Escape Chinese as \uXXXXUnicode ConverterUseful when debugging encoding
Turn a byte stream into readable textBase64 Encode/DecodeBase conversion handles numbers, not bytes
Verify a file has not changedSHA HashThe classic use of a hex digest

#Frequently asked questions

#My password is definitely correct, but login still fails. Why?

Suspect full-width characters first. An IME in punctuation mode produces full-width letters, digits and underscores, which are different code points and therefore never match the stored hash. Paste the password into Full/Half Width, convert it to half-width and try again - that confirms the theory in seconds.

#Is 0x10 ten or sixteen?

Sixteen. The 0x prefix means hexadecimal, so 0x10 is 1x16 + 0 = 16. Likewise 0b10 is binary 2 and 0o10 is octal 8. The same digits mean completely different values depending on the prefix, which is the most common mistake in base conversion.

#What are binary, octal and hexadecimal actually used for?

Hex packs binary data into a readable form - two characters per byte - which is why hashes and memory addresses use it. Octal survives mainly in Unix file modes such as chmod 755 and in some escape syntaxes. Binary is the underlying representation used for bitwise operations and flags. Decimal exists for humans; the machine only ever sees binary.

#Why is a full-width space so hard to track down?

It is U+3000, not U+0020, and on screen it just looks like slightly more space, so it survives copy and paste unnoticed. Worse, languages disagree about it: JavaScript's trim() and Python's strip() remove it, while Java's String.trim() only strips U+0020 and below. The same data behaves differently per language. Text Counter shows the byte count, which settles it.

#Does the base converter handle fractions and very large integers?

Yes. Integer parts are computed with BigInt, so values above 2^53 keep full precision. Fractional parts follow IEEE 754 binary floating point, so decimals such as 0.1 that have no finite binary form will lose a little precision. Negative values keep their sign. When precision is critical, pass the number as a decimal string instead.

Tools used in this guide

Related guides