/** * @param string $str * @return string */ function Utf7to8($str) { if (!ConvertUtils::IsUtf7($str)) { return $str; } $array = array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, 63, -1, -1, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1); $result = ''; $error = ''; $strlen = strlen($str); for ($i = 0; $strlen > 0; $i++, $strlen--) { $char = $str[$i]; if ($char == '&') { $i++; $strlen--; $char = isset($str[$i]) ? $str[$i] : null; if ($char === null) { break; } if ($strlen && $char == '-') { $result .= '&'; continue; } $ch = 0; $k = 10; for (; $strlen > 0; $i++, $strlen--) { $char = $str[$i]; $b = $array[ord($char)]; if (ord($char) & 0x80 || $b == -1) { break; } if ($k > 0) { $ch |= $b << $k; $k -= 6; } else { $ch |= $b >> -$k; if ($ch < 0x80) { if (0x20 <= $ch && $ch < 0x7f) { return $error; } $result .= chr($ch); } else { if ($ch < 0x800) { $result .= chr(0xc0 | $ch >> 6); $result .= chr(0x80 | $ch & 0x3f); } else { $result .= chr(0xe0 | $ch >> 12); $result .= chr(0x80 | $ch >> 6 & 0x3f); $result .= chr(0x80 | $ch & 0x3f); } } $ch = $b << 16 + $k & 0xffff; $k += 10; } } if ($ch || $k < 6) { return $error; } if (!$strlen || $char != '-') { return $error; } if ($strlen > 2 && $str[$i + 1] == '&' && $str[$i + 2] != '-') { return $error; } } else { if (ord($char) < 0x20 || ord($char) >= 0x7f) { return $error; } else { $result .= $char; } } } return $result; }