이모티콘은 U + xxxxx 형식을 사용하여 지정된 것 같습니다.
여기서 각 x는 16 진수입니다.
예를 들어 U + 1F615 는 “혼란 된 얼굴”에 대한 공식 유니 코드 컨소시엄 코드 입니다.
나는 종종 혼란스러워서이 상징에 대해 강한 친근감을 가지고 있습니다.
U + 1F615 I 유니 코드 문자 만 가능한 인코딩은 8, 16, 24 또는 32 비트가 필요하기 때문에 생각 5 16 진수는 5 × 4 = 20 비트가 필요한 반면, 표시 나에게 혼동된다.
이 기호가 bash에서 완전히 다른 16 진수 문자열로 표시되는 것으로 나타났습니다.
$echo -n ? | hexdump
0000000 f0 9f 98 95
0000004
$echo -e "\xf0\x9f\x98\x95"
?
$PS1=$'\xf0\x9f\x98\x95 >'
? >
U + 1F615 가 \ x00 \ x01 \ xF6 \ x15 와 같은 것으로 변환 될 것으로 예상했을 것 입니다.
이 두 인코딩 사이의 관계가 보이지 않습니까?
공식 유니 코드 컨소시엄 목록 에서 심볼 을 찾을 때이 지루한 방식으로 수동으로 변환하지 않고도 해당 코드를 직접 사용할 수 있기를 원합니다. 즉
- 일부 웹 페이지에서 심볼 찾기
- 웹 브라우저의 클립 보드에 복사
- 16 진 덤프를 통해 에코하여 리얼 코드를 발견하기 위해 bash에 붙여 넣습니다.
이 20 비트 코드를 사용하여 32 비트 코드가 무엇인지 확인할 수 있습니까?
이 두 숫자 사이에 관계가 있습니까?
답변
UTF-8
유니 코드 의 가변 길이 인코딩 입니다. ASCII 슈퍼 세트로 설계되었습니다. 인코딩에 대한 자세한 내용은 Wikipedia 를 참조하십시오 . \x00 \x01 \xF6 \x15
것 UCS-4BE
또는 UTF-32BE
인코딩.
로케일의 charmap이 UTF-8 (의 출력 참조 locale charmap
) 인 경우 유니 코드 코드 포인트에서 UTF-8 인코딩으로 가져 오려면 다음과 같습니다.
$ printf '\U1F615\n'
?
$ echo -e '\U1F615'
?
$ confused_face=$'\U1F615'
후자 는 POSIX 표준의 다음 버전에있을 것입니다 .
AFAIK는, 그 구문은 독립 실행 형 GNU에 의해 2000 년에 도입 printf
합니다 (반대 유틸리티 printf
에 가져온 GNU 쉘 유틸리티) echo
/ printf
/ $'...'
첫 번째 내장 명령 에 의해 zsh
2003 년에 불구하고 2010 년, 2004 년의 경우 ksh93, bash는 ( 제대로가 작동하지 2014 년까지 )이지만 다른 언어에서 영감을 얻은 것 같습니다.
ksh93
또한으로 지원 printf '\x1f615\n'
하고 printf '\u{1f615}\n'
.
$'\uXXXX'
및 $'\UXXXXXXXX'
지원하는 zsh
, bash
, ksh93
, mksh
와 FreeBSD sh
, GNU printf
, GNU echo
.
POSIX는 더 적은 자릿수를 허용하므로 향후 버전에서는 변경 될 가능성이 있지만 일부는 모든 자릿수 (와 \U0001F615
반대로 \U1F615
) 가 필요합니다 . (가) 경우 어떤 경우에, 당신은 모든 숫자를 필요 \UXXXXXXXX
와 같이 16 진수 다음에 될 \U0001F615FOX
대로 \U1F615FOX
했을 것이다 $'\U001F615F'OX
.
일부는 문자열이 구문 분석 될 때 또는 확장 될 때 현재 로케일 인코딩의 문자로 확장되며 일부는 로케일에 관계없이 UTF-8로만 확장됩니다. 현재 로캘의 인코딩에서 문자를 사용할 수없는 경우 동작은 셸마다 다릅니다.
따라서 최상의 이식성을 위해 UTF-8 로케일에서만 사용하고 모든 숫자를 사용하고 다음에서 사용하는 것이 가장 좋습니다 $'...'
.
printf '%s\n' $'\U0001F615'
참고 :
LC_ALL=C.UTF-8; printf '%s\n' $'\U0001F615'
또는:
{
LC_ALL=C.UTF-8
printf '%s\n' $'\U0001F615'
}
(을 포함한 모든 쉘에서 작동하지 않음 bash
(가) 때문에) $'\U0001F615'
되어 구문 분석 하기 전에 LC_ALL
할당됩니다. (또한 시스템 로케일라는 하리라는 보장이 없다 있습니다 C.UTF-8
)
필요한 것 :
LC_ALL=C.UTF-8; eval "confused_face=$'\U0001F615'"
또는:
LC_ALL=C.UTF-8
printf '%s\n' $'\U0001F615'
(복합 명령 또는 기능 내에 있지 않음).
반대로 UTF-8 인코딩에서 유니 코드 코드 포인트로 가져 가려면 이 다른 질문 이나 그 질문을 참조하십시오 .
$ unicode ?
U+1F615 CONFUSED FACE
UTF-8: f0 9f 98 95 UTF-16BE: d83dde15 Decimal: 😕
?
Category: So (Symbol, Other)
Bidi: ON (Other Neutrals)
$ perl -CA -le 'printf "%x\n", ord shift' ?
1f615
답변
다음은 UTF-32 (빅 엔디안)에서 UTF-8로 변환하는 방법입니다
$ confused=$(echo -ne "\x0\x01\xF6\x15" | iconv -f UTF-32BE -t UTF-8)
$ echo $confused
?
0x01F615
거기에 16 진수 값 이 있고 32 비트를 채우기 위해 추가 0이 채워져 있음을 알 수 있습니다 .
UTF-8 의 Wikipedia 페이지 는 유니 코드 코드 포인트에서 UTF-8 표현으로의 변환을 매우 명확하게 설명합니다. 그러나 쉘 스크립팅에서 직접 시도하는 것이 가장 좋은 아이디어는 아닙니다.
UTF-32 는 고정 너비이며 코드 포인트와 UTF-32 표현 간의 대응은 사소합니다. 값은 동일합니다.
답변
머리 나 종이에 좋은 방법 :
-
얼마나 많은 바이트가 될지 알아보십시오. U + 0080의 값은 1 바이트이고, U + 0800의 값은 2 바이트이고, U + 10000의 경우 3 바이트, 그렇지 않으면 4 바이트입니다. 귀하의 경우에는 4 바이트입니다.
-
16 진수를 8 진수로 변환하십시오
0373025
. -
끝에서 시작하여 한 번에 2 개의 8 진수를 제거하여 일련의 8 진수 값을 얻으십시오
037
030
025
. -
예상 바이트 수보다 8 진수 값이 적은 경우 시작 부분에 0을 더 추가하십시오
000
037
030
025
. -
첫 번째를 제외하고는 다음을 추가
0200
하십시오000
0237
0230
0225
. -
첫 번째로
0300
예상 길이가 2,0340
3 또는0360
4 인 경우 다음을 추가하십시오360
0237
0230
0225
.
이제 8 진 이스케이프 문자열로 작성하십시오 \360\237\230\225
. 원하는 경우 선택적으로 16 진으로 다시 변환하십시오.