백엔드 개발 PHP 튜토리얼 PHP 인코딩 변환 문제_php 기술에 대한 자세한 토론

PHP 인코딩 변환 문제_php 기술에 대한 자세한 토론

May 16, 2016 pm 08:10 PM
php 트랜스코딩

최근 유니코드 인코딩 변환이 필요해서 PHP의 라이브러리 함수를 확인해 봤는데 문자열을 유니코드로 인코딩하고 디코딩할 수 있는 함수를 찾을 수 없었어요! 글쎄, 찾을 수 없다면 직접 구현하십시오. . .

유니코드와 Utf-8 인코딩의 차이점

유니코드는 문자 집합이며 UTF-8은 유니코드 중 하나입니다. 유니코드는 고정 길이이고 더블 바이트인 반면, UTF-8은 가변입니다. 한자의 경우 유니코드가 UTF-8이 차지하는 바이트 비율을 차지합니다. 1바이트 적습니다. 유니코드는 2바이트이고 UTF-8의 중국어 문자는 3바이트를 차지합니다.

UTF-8로 인코딩된 문자는 이론적으로 최대 6바이트까지 가능하지만 16비트 BMP(Basic Multilingual Plane) 문자는 최대 3바이트까지만 가능합니다. 아래를 살펴보세요

UTF-8 인코딩 테이블:

U-00000000 - U-0000007F: 0xxxxxxx 
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx 
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx 
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
로그인 후 복사

xxx의 위치는 문자 인코딩 번호의 이진 표현으로 채워집니다. 오른쪽에 있는 x는 문자 인코딩 번호의 다중 바이트 문자열을 표현하는 데 덜 특별한 의미를 갖습니다. 다중 바이트 문자열에서 첫 번째 바이트 시작 부분의 "1" 수는 전체 문자열의 바이트 수입니다. 첫 번째 줄은 1바이트인 ASCII 인코딩과 호환되도록 0으로 시작하고, 두 번째 줄은 더블바이트 문자열, 세 번째 줄은 한자와 같은 3바이트입니다. (개인의견: 사실 그냥 앞에 1의 개수를 바이트 수라고 생각하면 됩니다)

유니코드를 Utf-8로 변환하는 방법

유니코드를 UTF-8로 변환하려면 물론 차이점이 무엇인지 알아야 합니다. 유니코드의 인코딩이 어떻게 UTF-8로 변환되는지 살펴보겠습니다. UTF-8에서 문자의 바이트가 0x80(128)보다 작으면 1바이트를 차지하는 ASCII 문자이며 변환이 없습니다. UTF-8은 ASCII 인코딩과 호환되기 때문입니다. 유니코드에서 한자 "you"의 인코딩이 "u4F60"인 경우 100111101100000으로 바이너리로 변환한 후 UTF-8 방식에 따라 변환한다. 이진수는 유니코드 이진수에서 한 번에 6비트씩 가져올 수 있습니다. 예를 들어 위 이진수는 아래 표시된 형식으로 가져올 수 있으며 그 이하의 숫자는 형식에 따라 채워집니다. 8비트 이상은 0으로 채워집니다.

코드 복사 코드는 다음과 같습니다.
유니코드: 100111101100000                                         

utf-8: 11100100,10111101,10100000 E4BDA0


위에서 유니코드와 UTF-8 간의 변환을 직관적으로 볼 수 있습니다. 물론 UTF-8의 형식을 알고 나면 이를 해당 위치에 넣는 역연산을 수행할 수 있습니다. 형식에 따라 바이너리를 꺼내서 결과 유니코드 문자로 변환합니다(이 작업은 "변위"를 통해 완료할 수 있습니다). 예를 들어 위의 "you" 변환에서는 그 값이 0x800보다 크고 0x10000보다 작으므로 3바이트 저장소로 판단할 수 있습니다. 그러면 최상위 비트를 "12"비트만큼 오른쪽으로 이동해야 합니다. 3바이트 형식에 따르면 가장 높은 비트는 11100000(0xE0) 또는 (|)로 가장 높은 값을 얻습니다. 같은 방법으로 두 번째 자리도 "6" 비트만큼 오른쪽으로 이동하고, 가장 높은 자리와 두 번째 자리의 바이너리 값이 남게 되는데, 111111(0x3F)로 위치(&) 연산을 수행하면 계산할 수 있다. ), 11000000(0x80) 또는 (|)로 합산됩니다. 세 번째 비트를 이동할 필요가 없습니다. 마지막 6비트를 직접 가져온 다음(&와 111111(ox3F)) 11000000(0x80)을 OR(|)하면 됩니다.

Utf-8을 다시 유니코드로 변환하는 방법

물론 UTF-8에서 유니코드로의 변환도 쉬프트 등을 통해 이루어지는데, 이는 UTF-8 형식의 해당 위치에 있는 이진수를 추출하는 것입니다. 위의 예에서 "you"는 3바이트이므로 각 바이트를 높은 비트에서 낮은 비트까지 처리해야 합니다. UTF-8에서 "당신"은 11100100,10111101,10100000입니다. 상위 비트, 즉 첫 번째 바이트 11100100은 "0100"을 빼는 것입니다. 이는 매우 간단합니다. 11111(0x1F)과 AND(&)를 취하면 됩니다. 매번 6자리 숫자를 가져오므로 가장 높은 위치는 12번째 비트 이전에 와야 합니다. 따라서 얻은 결과를 왼쪽으로 12비트 이동해야 하며, 이제 가장 높은 비트는 0100,000000,000000이 됩니다. 두 번째 비트는 "111101"을 꺼내는 것이므로 두 번째 바이트 10111101과 111111(0x3F)만 AND(&)하면 됩니다. 결과를 왼쪽으로 6비트 이동하여 최상위 바이트 또는 (|)의 결과를 취하면 두 번째 비트가 완성되어 결과는 0100,111101,000000이 됩니다. 비유하자면, 마지막 숫자는 111111(0x3F)과 직접 AND(&)된 다음 이전 결과와 OR(|)되어 결과 0100,111101,100000을 얻습니다.

PHP 코드 구현

/**
 * utf8字符转换成Unicode字符
 * @param [type] $utf8_str Utf-8字符
 * @return [type]      Unicode字符
 */
function utf8_str_to_unicode($utf8_str) {
  $unicode = 0;
  $unicode = (ord($utf8_str[0]) & 0x1F) << 12;
  $unicode |= (ord($utf8_str[1]) & 0x3F) << 6;
  $unicode |= (ord($utf8_str[2]) & 0x3F);
  return dechex($unicode);
}

/**
 * Unicode字符转换成utf8字符
 * @param [type] $unicode_str Unicode字符
 * @return [type]       Utf-8字符
 */
function unicode_to_utf8($unicode_str) {
  $utf8_str = '';
  $code = intval(hexdec($unicode_str));
  //这里注意转换出来的code一定得是整形,这样才会正确的按位操作
  $ord_1 = decbin(0xe0 | ($code >> 12));
  $ord_2 = decbin(0x80 | (($code >> 6) & 0x3f));
  $ord_3 = decbin(0x80 | ($code & 0x3f));
  $utf8_str = chr(bindec($ord_1)) . chr(bindec($ord_2)) . chr(bindec($ord_3));
  return $utf8_str;
}

로그인 후 복사
테스트해봤습니다

$utf8_str = '我';

//这是汉字“你”的Unicode编码
$unicode_str = '4f6b';

//输出 6211
echo utf8_str_to_unicode($utf8_str) . "<br/>";

//输出汉字“你”
echo unicode_str_to_utf8($unicode_str);

로그인 후 복사

위 변환은 한자(보통 비ASCII) 테스트를 위한 것입니다. 왜냐하면 ASCII라면 계속해서 동일할 것이고 그렇게 많은 노력을 기울일 필요가 없기 때문입니다.

또한 이 두 기능은 단순하게 구현되었으며 단일 문자[완전한 utf8 문자 또는 완전한 유니코드 문자] 간의 변환만 지원하므로 이해하면 원하는 만큼 확장할 수 있습니다. . . .

위 내용은 이 글의 전체 내용입니다. 모두 마음에 드셨으면 좋겠습니다.

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

뜨거운 기사 태그

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드

CakePHP 날짜 및 시간 CakePHP 날짜 및 시간 Sep 10, 2024 pm 05:27 PM

CakePHP 날짜 및 시간

CakePHP 프로젝트 구성 CakePHP 프로젝트 구성 Sep 10, 2024 pm 05:25 PM

CakePHP 프로젝트 구성

CakePHP 파일 업로드 CakePHP 파일 업로드 Sep 10, 2024 pm 05:27 PM

CakePHP 파일 업로드

CakePHP 라우팅 CakePHP 라우팅 Sep 10, 2024 pm 05:25 PM

CakePHP 라우팅

CakePHP 토론 CakePHP 토론 Sep 10, 2024 pm 05:28 PM

CakePHP 토론

CakePHP 빠른 가이드 CakePHP 빠른 가이드 Sep 10, 2024 pm 05:27 PM

CakePHP 빠른 가이드

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법

See all articles