Example: \N{THINKING FACE}\N{FACE WITH TEARS OF JOY}\N{FACE SCREAMING IN FEAR}\N{SMILING FACE WITH SMILING EYES AND THREE HEARTS}\N{PERSON DOING CARTWHEEL}\N{FACE WITH NO GOOD GESTURE}\N{ZERO WIDTH JOINER}\N{FEMALE SIGN}\N{VARIATION SELECTOR-16}\N{EYES}\N{ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE}\N{SQUARED COOL}\N{VARIATION SELECTOR-16}
In UTF-8:
00000000: f09f a494 f09f 9882 f09f 98b1 f09f a5b0 ................
00000010: f09f a4b8 f09f 9985 e280 8de2 9980 efb8 ................
00000020: 8ff0 9f91 80f0 9f94 9bf0 9f86 92ef b88f ................
In GB 18030: 00000000: 9530 cd34 9439 fc38 9530 8335 9530 d636 .0.4.9.8.0.5.0.6
00000010: 9530 d130 9530 8535 8136 a439 a1e2 8431 .0.0.0.5.6.9...1
00000020: 8235 9439 cf38 9439 e537 9439 8b32 8431 .5.9.8.9.7.9.2.1
00000030: 8235 .5I'm only scratching the surface right now, and just wrote a CPG 932 → Unicode lookup utility. https://pastebin.com/4PYmEjQZ
(For internal testing, forgive any sloppiness, but feel free to use the kuten table if you happen to have a niche project with one-way mapping. The tables themselves are facts and not creative expression, so should not be copyrightable, but I'm dedicating the project to the public domain anyway.)
UTF-16 is the warty bit. Why? Because it was designed to be a fixed-width encoding, under the assumption that 65,536 code points would cover all languages we needed. Well, spoiler alert: this wasn't enough, even with the mess that was UniHan. So they carved out a chunk of those code points from the 16-bit part of Unicode, called them "surrogate code points", and used them to extend UTF-16 into a variable-width encoding. Thus, they could have 16 planes of 65,536 characters each. They weren't valid characters beforehand, so obviously we could just repurpose them as flags for "astral" characters outside the Basic Multilingual Plane. Simple, right?
Except that plenty of code to work with UTF-16 strings already existed, and assumed UTF-16 was a fixed-width encoding. If you chucked an astral character at it, it'd think it's two rather than one. It'll also happily split or rearrange astral characters into invalid sequences of codepoints. Furthermore, if you ask these systems for UTF-8, it'll happily encode the surrogates, leading to two nested layers of variable encodings.
Oh, and the two biggest users of UTF-16 were Windows NT and JavaScript. So we're absolutely stuck with fixed-length UTF-16 and the mangled WTF-8[1] encodings they will output until the end of time. Furthermore, if we ever do fill up the astral planes, we'll have to define superastral characters, which means having supersurrogate code points that will break modern UTF-16 again and make WTF-8 handling even more complicated.
[0] Unless you use MySQL, where someone decided to break UTF-8 early on and now there's "utf8mb4" to un-break it.
[1] UTF-8 which contains encoded UTF-16 surrogates, as defined in https://simonsapin.github.io/wtf-8/
Utf-16 is either 2 or 4 bytes long per code point (not per character) but a lot of older programs (and older programmers) see it as a "2 byte per code point" string.
There is a 2 byte per code point encoding, its called UCS2 so its important to make sure when something says utf-16 they don't mean UCS2.
I am not familiar enough with UCS2 to know if it also supports multiple code points per char - but I expect it does - so the mental model of 2 bytes per char breaks down even there.
"one code point in unicode does not necessarily map to one character on the screen."
A "character" can, and often does, get constructed from multiple code points.
This doesn't help an already complicated sorting issue (who knew "sort these names alphabetically" could be an ambiguous statement).
Also, importantly, some characters are not represented at all. For example, there is no codepoint or combination of characters that distinguishes a capital Turkish dotless I from its identical looking but conceptually different sibling the Latin capital I. Similarly for capital Turkish dotted İ.
I find it extremely weird that two codepoints couldn't have been spared, yet we have gradations of skin tone in emoji. One can use composition to deal with the round-trip from i -> İ -> i (within a closed ecosystem), but even that fails when it comes to ı -> I -> ı.
A case in point are the product pages for my friend's book on Amazon. Compare "Sınır Ötesi" to "Sinir Ötesi". The former means "beyond borders" whereas the latter means "exceedingly irritating".
Yet, because there is no unambiguous representation of the Turkish I's, the rendering makes an assumption on the basis of the domain. Note that all other non-US ASCII letters involved are rendered correctly.
\c[PERSON FROWNING, ZERO WIDTH JOINER, PROGRAMMER]
[tr]: https://www.amazon.com.tr/Gezging%C3%B6z-S%C4%B1n%C4%B1r-T%C...
[us]: https://www.amazon.com/Gezging%C3%B6z-Sinir-T%C3%BCrkiye-Mir...
The Turkish alphabet ISO 8859-9 was published in 1988, and it doesn't distinguish between I and I, since why would it? It's a byte encoding designed specifically to accommodate Turkish.
Unicode has a principle of adopting whatever makes it easy to convert from the preferred legacy encoding to Unicode, and for Turkish that meant using the same code point for I in both Turkish and practically everywhere else, since I is in ASCII and the bulk of Latin-based character encodings are based on ASCII.
I point this out because it could indeed have been the case that they ended up with separate encodings, which would have solved your problem.
But it wouldn't have solved the actual problem, which is the collation and casing are locale-specific according to Unicode, and indeed they must be. Example: in Dutch the letters 'ij' are one letter for collation purposes, as well as for casing, see https://en.wikipedia.org/wiki/IJsselstein for an example.
This is of course impossible to get correct if the application doesn't know it's dealing with Dutch, which it often can't know. The very same problem you have with Turkish.
Not really the same. The brokenness of more complex text transformations (collation, alphabetization, upper-casing, lower-casing) seems a bit less catastrophic than breaking the fundamental ability to unambiguously draw the character.
If you don't think that's an important goal.... then what are "character sets" for anyway?
That historic process does not preclude introducing two extra codepoints to at least allow for the possibility of correctly encoding the upper case of "ı" and the lower case of "İ".
That already is ambiguous without considering text encodings or even computers.
Sort order depends on locale (example, “in Lithuanian, "y" is sorted between "i" and "k"”) and within some locales even on the goal of the sorting (example: “in German dictionaries, "öf" would come before "of". In phone books the situation is the exact opposite.”
(Both examples taken from https://unicode-org.github.io/icu/userguide/collation/, which has many more examples)
Also, on that “one code point in unicode does not necessarily map to one character on the screen”, I think it’s important to use consistent terminology. The screen doesn’t show characters but glyphs.
Thus alphabetical order becomes ambiguous depending on where you are.
_then_ you discover some symbol sets / languages don't have an order at all. Oh the world is complicated. I wish I was 4 again.
Like "the" word, or person with some titles... While ofc. the title itself is sorted in that position...
I am only aware of “of” before “öf”, e.g. in Grimmʼs dictionary, the greatest dictionary of German itself, “offen” ‘open (adj.), openly’ comes before “öffen”, a variant of “öffnen” ‘to open’.
When I have to sort strings in German, I make a sortstring by throwing out diacritics (via Unicode Normal Form “K”anonical Decomposition) and changing “ß” to “s”. Then I order by a tuple of this sortstring and the original string.
What you infer about sorting is better described as collation and is a separate set of problems. https://www.unicode.org/collation/
There can be multiple collations for the same encoding and even for the same language inside the same encoding.
PS: As a matter of fact in some database like PostgreSQL you can define different collations for each columns if needed.
I did a quick check and saw that I can specify Hungarian in MySQL as a collation for a table and I also know that it's available in Java and even JavaScript.
⸻
1. This sorting is wrong not just for Hungarian but for every language including English which would expect, e.g., naïve to be sorted between nag and nanny and not after nay.
the second character of sœur (o or the ligature?)
the second character of حبيبي (the canonical form ب or the contextual form ﺒ ?)
the third character of есть (Cyrillic t with or without soft sign, which is always a separate code point and always displayed to the right but changes the sound?)
the first character of 실례합니다 (Korean phoneme or syllabic grapheme?)
the first character of ﷺ or ﷽ ?
The main issue isn't programming language support, it's ambiguity in the concept of "character" and conventions about how languages treat them. Imagine how the letter i would be treated if Unicode were invented by a Turk. The fundamental issue here is that human communication is deeply nuanced in a way that does not lend itself well to systematic encoding or fast/naive algorithms on that encoding. Even in the plain ASCII range it's impossible to know how to render a word like "ANSCHLUSS" in lower case (or how many 'characters' such a word would have) without knowledge of the language, country of origin, and time period in which the word was written.
All of this already standardised in detail in Unicode. There is no ambiguity. Read it some time to mend your ignorance, it answers all your questions with justification, I am willing to spend time on the answers only.
> the second character of sœur (o or the ligature?)
the letter œ, both character (C) and grapheme cluster (GC)
the letter o does not exist in this text (again, according to the standard)
> the second character of حبيبي (the canonical form ب or the contextual form ﺒ ?)
the letter ب, both C and GC
the letter ﺒ is a presentation form and does not exist in this text
> the third character of есть (Cyrillic t with or without soft sign
the letter т, both C and GC
the letter ь, both C and GC, is the 4th in the text
> the first character of 실례합니다 (Korean phoneme or syllabic grapheme?)
the letter 실, both C and GC
the text does not contain the jamo ᄉ
Unicode is not concerned with phonemes, only with writing
> the first character of ﷺ
is entirely itself, the letter ﷺ, both C and GC
> or ﷽ ?
is entirely itself, the symbol ﷽, both C and GC
$string = "漢字";
But if you are using say UTF-8 and one of those Chinese characters has one of its bytes have a value of 34 (the ascii value of "), then wouldn't the string terminate prematurely?
Edit: to answer my own question, quote from wikipedia: ASCII bytes do not occur when encoding non-ASCII code points into UTF-8
Of greater moment is that the article keeps talking about "characters", which is an undefined term in Unicode. Unicode offers you code points, code units, graphemes, grapheme clusters, and ... other things, none of which maps to the grouping of dots you see on your screen (and probably cannot imagine how to type in).
"Character" has outlived its sell-by date. Let it be retired and buried with dignity, but with a good thick slab of concrete on top.
It also fails to mention "expanded form" and "canonical form", and other ways that two completely different sequences of bits mean, at some level, the same text. Different forms are convenient for different things; there is a shortest possible representation nice for sending and storing, and a maximally decomposed representation that might be best for editing if you like adding and removing diereses ("umlauts") and accents piecemeal.
And it fails to mention WTF-8, a way to package up byte sequences that are not valid UTF-8, but may have valid UTF-8 characters that you want to display in case they offer the poor human a clue as to what was intended. WTF-8 sequences often arise in file systems and databases that don't enforce any particular encoding, but just store whatever bytes the benighted programs users run provide as, e.g., names for files. You wish you could display them in sorted order. There had better be a way to point at it, because there is no way to type it. But you have to store it, because that is the only way to tell the OS which file you wanted to rename or delete. Deletion is tempting, but we can't, always, can we?.
https://w3techs.com/technologies/overview/programming_langua...
It is not possible to determine with certainty how a given set of HMTL/CSS/Javascript was generated. They admit to it in their FAQ: https://w3techs.com/faq
They also state which web sites they survey, which doesn't include the web site many of us use most of their workday: the one of your employer which very likely is either made using ASP.Net or Java and isn't available on the Internet.
None of which should be taken as argument that PHP isn't still a major, if not even dominant, language to create dynamic web pages on the Internet. shudder