LabHub
배우기 러닝패스 코스

고객 데이터 다루기 · 글자가 깨졌다 · 실습

이름 칸이 전부 네모다 — 판정 도구를 만든다

LabHub 에서 이어서 보기

목표

고객이 보낸 파일의 인코딩을 추측하지 않고 판정하는 도구 enc_probe.py 를 만든다. BOM 과 UTF-8 디코딩 가능성에서 시작해 후보 인코딩과 표본 대조로 내려가고, 이중 인코딩을 되살리고, 되살릴 수 없는 파일을 가려내고, 정규화와 보이지 않는 문자가 비교를 어떻게 망가뜨렸는지를 자기 데이터로 증명한다.

왜 중요한가

텍스트 파일 안에는 인코딩이 적혀 있지 않다. 그래서 "무슨 인코딩이냐" 는 물음에는 언제나 절차로만 답할 수 있다. 에디터 메뉴를 눌러 보는 방식은 파일이 셋일 때만 통하고, 무엇보다 맞았는지를 눈으로만 판단하게 만든다.
판정이 끝나면 파일은 세 부류로 갈린다. 제대로 읽히는 것, 한 번 잘못 읽혀 굳었지만 되돌릴 수 있는 것, 그리고 글자가 뭉개져 원래 바이트를 알 수 없는 것이다. 마지막 부류를 붙들고 시간을 쓰는 것은 노력이 아니라 낭비다 — 그 파일은 다시 받아야 한다. 이 구별을 코드로 할 수 있어야 고객에게 무엇을 요청할지 말할 수 있다.
그리고 글자가 멀쩡히 보이는데 안 맞는 자리가 있다. 같은 한글이 완성형과 자모 분해형으로 나뉘어 저장되면 화면은 같고 바이트는 다르다. 눈에 안 보이는 NBSP 와 제로폭 공백도 마찬가지다. 조인 결과가 0건인데 원인이 화면에 안 보이는 상황은 여기서 나온다.
채점기는 여러분의 문구를 믿지 않는다. 임시 디렉터리에 채점기가 만든 파일을 차려 놓고 여러분의 도구를 실제로 실행해 판정을 대조한다. 이름과 행 수는 실행마다 바뀐다.

단계

1. /root/enc/gen_inbox.py 를 만들어 실행해 /root/enc/inbox 아래 일곱 파일을 만드세요. 같은 24명의 명부가 일곱 가지 상태로 저장됩니다.
2. /root/enc/enc_probe.pydetect 를 만들어 BOM·UTF-8 디코딩 가능성·후보 인코딩·표본 대조 순서로 인코딩을 판정하게 하세요.
3. decode 를 더해 판정한 인코딩으로 읽어 UTF-8 로 표준출력에 내게 하고, 수신함 전체를 /root/enc/norm 아래 같은 이름으로 통일해 저장하세요.
4. repair 를 더해 이중 인코딩을 되살리게 하고, detect 가 그런 파일에 mojibake 를 true 로, verdict 를 mojibake 로 답하게 하세요.
5. detectlossy 를 더해 U+FFFD 가 남은 파일의 verdict 를 lost 로 하고, 수신함 판정을 /root/enc/lost.json 에 적으세요.
6. keys 를 더해 이름 칸을 NFC 로 정규화한 비교용 키로 내게 하고, NFD 판과 UTF-8 판의 이름이 정규화 전후로 몇 건 맞는지를 /root/enc/join_report.json 에 적으세요.
7. scan 을 더해 보이지 않는 문자를 코드포인트별로 세게 하고, keys 가 그것들을 걷어 내게 한 뒤 /root/enc/invisible_report.json 에 적으세요.
8. 수신함 일곱 파일을 한 번에 처리해 /root/enc/enc_report.json/root/enc/enc_report.md 를 만드세요.

참고

단계 8개

  1. 일곱 가지 상태의 같은 명부 만들기
  2. 추측하지 않고 판정하기
  3. 판정한 대로 읽어 UTF-8 로 통일하기
  4. 한 번 잘못 읽혀 굳은 글자 되살리기
  5. 되살릴 수 있는 것과 이미 잃은 것 가르기
  6. 같아 보이는데 안 맞는 이름
  7. 눈에 안 보이는 글자가 키에 섞였다
  8. 수신함 한 장으로 보고하기