� is mojibake for the Replacement Character ("�").
What's happening is that your website encoding is ISO 8859-1 ("Western"), while Google is trying to interpret the bytes as UTF-8. In UTF-8, bytes between 0 and 127 (0x00 to 0x7F) are only valid as standalone bytes, whereas bytes between 128 and 255 (0x80 to 0xFF) are only valid in groups of two or more.*
Code pages, however, do allow standalone bytes between 0x80 and 0xFF, which is where Western has the special characters located, and a common side effect is seeing the replacement character where the invalid bytes are.
The problem in your case is that the bytes that represent the special characters are also getting corrupted, since something along the way thinks that the replacement character was part of the original document and is encoding it in UTF-8. In UTF-8, the replacement character is represented as EF BF BD
, and this sequence is what has taken the place of every “illegal” byte. If EF BF BD
is interpreted as Western, EF
becomes ï, BF
becomes ¿, and BD
becomes ½.
Since all of the invalid bytes have been replaced with the replacement character, all of the special characters now become �, regardless of what they were originally.
My personal recommendation is to re-encode your entire site as UTF-8, since the vast majority of websites on the Internet use UTF-8 nowadays and there are almost no good reasons to use legacy encodings anymore.
Here is a UTF-8 to Western debugging table showing Mojibake for the most common special characters.
* The reason why this is done is to allow UTF-8 to maintain backwards compatibility with ASCII while eliminating the need to set a specified code page or switch between code pages when encoding characters located beyond U+007F. During UTF-8's development, an algorithm to convert code points to byte sequences was developed to allow a somewhat easy way to tell which bytes should be treated as groups and how many bytes are in that group:
- If we are reading UTF-8 encoded text and the byte after the one we are currently on starts with C or D (i.e. it has 1100 or 1101 as the first four bits), this tells us that the next two bytes should be interpreted as a group, which is valid for all Unicode characters up to U+07FF, the end of the block for N'Ko characters.
- If the next byte starts with E (1110), then we need to interpret the next three bytes as a group, which is needed for all characters from U+0800 (the start of the Samaritan block) up to U+FFFF (the end of the Basic Multilingual Plane).
- If the next byte starts with F (1111), we are now beyond the Basic Multilingual Plane, so we need to treat the next four, five, or six bytes as a group, depending on the latter four bits of the next byte.
When an application converts text encoded in Western or Windows-1252 into UTF-8, standalone bytes 128 and greater are converted to multi-byte sequences (because, again, UTF-8 does not allow individual bytes greater than 127). For example, the German word für is encoded as 66 FC 72
in Western, but becomes 66 C3 BC 72
in UTF-8.