EUC(5)

πŸ“¦
version 15.1 Β· 2 versions
, in freebsd 15.1

πŸ’– EUC(5) β€” the manual page, but make it group-chat πŸ’–

okay so this is euc, bestie β€” the EUC encoding of wide characters page, and it's lowkey iconic once you get the vibe. it lives in the File Formats Manual section of the man pages, iykyk πŸŽ€


✨ SYNOPSIS ✨

like, here's the shape of the thing, exactly as written:

ENCODING "EUC"

VARIABLE len1 mask1 len2 mask2 len3 mask3 len4 mask4 mask

that second line is the whole personality btw β€” four codesets, four lengths, four masks, and one big global mask to rule them all πŸ‘‘


🌸 DESCRIPTION 🌸

so EUC implements a system of 4 multibyte codesets, okay? four of them. not three, not five. four. and each one has its own lil starting-byte vibe check:

  • a multibyte character in the first codeset is made of len1 bytes, starting with a byte in the range of 0x00 to 0x7f. and because we still want plain ASCII to work, len1 is always 1. cute, right? 🫢
  • a multibyte character in the second codeset is len2 bytes, starting with a byte in the range of 0x80-0xff, excluding 0x8e and 0x8f. sorry bestie, those two are taken πŸ’…
  • a multibyte character in the third codeset is len3 bytes, and it starts with the byte 0x8e. that's literally its whole thing ✨
  • a multibyte character in the fourth codeset is len4 bytes, starting with the byte 0x8f. also its whole thing 🌈

🧚 the wchar_t glow-up (aka how the bytes get turned into a wchar_t) 🧚

the wchar_t encoding of EUC multibyte characters is dependent on the len and mask arguments. first, the bytes get moved into a wchar_t like this:

byte0 << ((lenN-1) * 8) | byte1 << ((lenN-2) * 8) | ... | bytelenN-1

then β€” and this is the part that matters β€” the result is ANDed with ~mask and ORed with maskN. so it's a little mask-and-shift situation. very demure, very mindful πŸŽ€

and here's the spicy bit: codesets 2 and 3 are special πŸ”₯ because the leading byte (that's 0x8e or 0x8f) is first removed, and the lenN argument is reduced by 1 before all that shifting happens. so like... the leading byte did its job and then dipped πŸ™ˆ


πŸ“ the example, because an example ATE πŸ“

the ja_JP.eucJP locale has this exact VARIABLE line:

VARIABLE        1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080

and here's what each codeset looks like in that case, no cap:

  • Codeset 1 consists of the values 0x0000 - 0x007f.
  • Codeset 2 consists of the values who have the bits 0x8080 set.
  • Codeset 3 consists of the values 0x0080 - 0x00ff.
  • Codeset 4 consists of the values 0x8000 - 0xff7f excluding the values which have the 0x0080 bit set.

and notice β€” notice it, bestie β€” that the global mask is set to 0x8080. that implies that from those 2 bits the codeset can be determined. two bits. that's all it takes to know which codeset you're in. main character energy honestly πŸ‘‘


πŸ¦‹ SEE ALSO πŸ¦‹

go bother these pages next, they're the friend group:


nothing dangerous here to warn you about, but you do have to keep your len and mask arguments straight or the whole wchar_t vibe check falls apart. literally. careful with those. πŸ’…

and that's the page!! πŸ’–βœ¨πŸŽ€πŸ¦‹πŸŒΈπŸ«Ά

this lil beauty comes to you from Debian, dated September 9, 2019, and it's EUC(5) all day every day. mwah πŸ’‹ slay, bye πŸ‘‹

πŸ“¦ where this page comes from
  • freebsd 15.1: base 15.1
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms