이모 티 콘 이 Android JNI 에서 의 호환성 문제 에 대한 상세 한 설명

5256 단어 emojiandroidjni
원인
최근 문제 가 발생 했 습 니 다.어떤 문자열 을 MD5 로 계산 한 후 이 문자열 을 암호 화하 여 MD5 와 함께 서버 에 올 렸 습 니 다.서버 복호화 후 다시 계산 한 md5 는 업 로드 된 MD5 와 일치 하지 않 는 것 을 발 견 했 습 니 다.문제 가 된 문자열 에는 예외 없 이 이모 티 콘 이 있 었 습 니 다.하지만 내 가 직접 표정 이 있 는 문자열 을 만들어 올 리 는 것 은 문제 가 없다.
최종 확인 은 Android 5.1 이하 jstring->char 배열 에서 발생 한 문제 입 니 다.다음은 하나의 예 시 를 통 해 이 과정 을 복원 한다.
이벤트 복원
문자열 s,String s = "\uD83D\uDC8B";,대응 하 는 표정 💋 이 있다 고 가정 합 니 다.getBytes() 방법 을 호출 하면 해당 하 는 byte 배열 은 [-16, -97, -110, -117] 이 고 16 진법 으로 [f0, 9f, 92, 8b] 을 출력 하 는 것 을 볼 수 있 습 니 다.
String 의 native 방법 으로 매개 변 수 를 정의 합 니 다.public native String test(String str); .해당 하 는 C/C+코드 에서 env->GetStringUTFChars 을 통 해 들 어 오 는 String 에 대응 하 는 char 배열 을 가 져 오고 char 배열 의 모든 요 소 를 16 진법 으로 출력 합 니 다.
안 드 로 이 드 7.1.2 의 테스트 기 에서 네 이 티 브 레이 어 출력 결 과 는 [f0, 9f, 92, 8b] 으로 자바 의 byte 배열 과 같 았 으 나 안 드 로 이 드 4.4.4 의 테스트 기 에서 출력 결 과 는 [ed, a0, bd, ed, b2, 8b] 이 었 다.암호 화 된 결과 가 다 릅 니 다.
서버 는 기 존 안 드 로 이 드 의 데 이 터 를 복호화 한 후 [ed, a0, bd, ed, b2, 8b] 을 받 았 으 며,계산 MD5 는 당연히 [f0, 9f, 92, 8b] 계산 MD5 와 같 을 수 없다.
Unicode、UTF-8、UTF-16
위 에 있 는 두 종류의 byte 배열 이 어떻게 왔 는 지 잘 모 르 는 사람 이 있 을 것 이다.우선 UTF-8 과 UTF-16 은 모두 유 니 코드 의 실현 이라는 것 을 알 아야 한다.\uD83D\uDC8B 은 사실 UTF-16 의 큰 표현 형식 으로 0xFFFF(0x 10000~0x10FFFF)이상 의 유 니 코드 에 대해 UTF-16 로 전환 하 는 절 차 는 다음 과 같다.
  • 유 니 코드 를 0x 10000 으로 줄 이면 길이 가 20bit 인 값 이 됩 니 다.
  • 은 첫 번 째 단계 인 20bit 의 높이 10bit 와 0xD 800 을 진행 하거나 연산 하여 UTF-16 의 고위 대 리 를 받는다.
  • 은 첫 번 째 단계 인 20bit 의 낮은 10bit 와 0xDC 00 을 진행 하거나 연산 하여 UTF-16 의 낮은 대 리 를 받는다.
  • 고위 에이전트+하위 에이 전 트 는 유 니 코드 에 대응 하 는 UTF-16 의 대 단 형식 입 니 다.
  • 이 단계 에 따라 반추:
  • \uD83D\uDC8B 의 바 이 너 리 1101 1000 0011 1101 1100 1000 1011 이면 고위 대 리 는 1101 1000 0011 1101 이 고 낮은 대 리 는 1101 1100 1000 1011 이다.
  • 고위 대 리 는 높 은 10bit 와 0xD 800 으로 진행 되 거나 연산 되 기 때문에 높 은 10bit 는 00 0011 1101 이다.
  • 저 위 대 리 는 낮은 10bit 와 0xDC 00 에서 진행 되 거나 연산 되 기 때문에 낮은 10bit 는 00 1000 1011 이다.
  • 모든 20bit 의 값 은 0000 1111 0100 1000 1011 이다.
  • 에 0x 10000 을 더 하면 0001 1111 0100 1000 1011,즉 0x1F48B 이다.
  • 그래서 표정💋대응 하 는 유 니 코드 는 0x1F48B 입 니 다.

    UTF-8 은 N 개의 바이트 에서 차지 하 는 기호(N>1)에 대해 서 는 첫 번 째 바이트 앞 N 자 리 는 모두 1,N+1 자 리 는 0 이 고,뒤의 바이트 앞 2 자 리 는 10 이 며,그 다음 에 유 니 코드 의 바 이 너 리 를 빈 바 이 너 리 에 채 우 고 빈 자 리 는 0 을 보충 하 는 규칙 이다.따라서 위의 유 니 코드 0x1F48B 가 UTF-8 로 전환 하려 면 4 개의 바이트 가 필요 합 니 다.
    11110 000
    10 011111
    10 010010
    10 001011
    즉,0xF09F928B,이것 이 바로[f0,9f,92,8b]이 byte 배열 의 유래 이다.

    그럼[ed,a0,bd,ed,b2,8b]이 byte 배열 은 어떻게 된 거 예요?이것 은\uD83D\uDC8B 를 2 개의 단독 문자 로 처리 한 것 이다.위의 유 니 코드 에서 UTF-8 로 전환 하 는 논리 에 따 르 면 유 니 코드 0xD83D 는 UTF-8 에서 1110 1101 10 100000 10 111101,즉 0xEDA0BD,유 니 코드 0xDC8B 는 UTF-8 에서 1110 1101 10 110010 001011,즉 0xEDB28B 로 전환 했다.

    총결산
    이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기