수십개의 gif 파일을 다루는 일을 하다가 신기한 점을 발견했다.

사용자 삽입 이미지


바로 파일명이 'res9' 다음에 'res10'이 오도록 정렬되어 있다는것!!

파일명을 정렬할 때 단순히 문자열로 비교한다면 'res1' 다음에는 'res10'이 와야한다. 'cast', 'cat' 그리고 'castle' 이 세 단어가 사전에는 'cast' - 'castle' - 'cat' 순서로 실려 있듯이. 그런데 저런 식으로 정렬이 되었다는 것은 파일명 정렬 알고리즘이 'res' 뒤에 붙은 숫자를 문자열이 아닌 숫자로 인식한다고 볼 수 있다.

정확히 어떤 기준일지 궁금해서 약간 실험을 해봤다.
사용자 삽입 이미지

'-'는 컴퓨터에서는 사전순으로 정렬할 때 숫자보다 앞에 있는 것으로 취급된다 (아스키 코드값이 숫자보다 작다). 이 결과를 분석해 보면
  1. '--21'을 '-' 와 -21로 해석하지 않았다. 즉, 음수는 처리하지 않는다.
  2. '-11'이 '--21'보다 앞에 있는 것으로 미루어 볼 때 숫자를 제외한 나머지 문자열을 기준으로 비교를 하는 것을 알 수 있다. 숫자를 제외하고 나면 '-11'은 '-'이 되고 '--21'은 '--'가 되므로 '-'이 '--'보다 앞에 온다.
  3. '--'와 '--21'의 순서로 볼 때 숫자가 있는 것이 숫자가 없는것보다 앞에 온다.
하지만 '--'과 '56', '--a'의 순서는 잘 이해가 가지 않는다.

어떤 방법으로 비교하면 이렇게 비교를 할 수 있을까. 문자열의 영역을 나누어 비교하면 이런 식으로 작동하게 만들 수 있을 것 같다. 예를 들면 '-3' 같은 경우에는 [문자열] [숫자] 로 영역을 나누는 것이다. 서로 다른 문자열들끼리 비교할 때에는 앞에서부터 영역별로 비교해나간다. 이 방법이라면 정렬 결과를 잘 설명할 수 있고 구현도 그리 복잡하지 않으므로 파일명 비교하는 부분은 이렇게 짜여졌으리라 예상할 수 있다.

그러면 '--'와 '56', '--a'는 어떻게 된것일까? 아마 [문자열] 영역을 [특수 문자열]과 [영문자]로 나누었을 것이다. 영역 간의 우선순위도 정해져야 하는데 아스키 코드상의 배열로 볼 때 [특수 문자열] - [숫자] - [영문자] 순서일 공산이 크다. '--'는 [특수문자열], '56'은 [숫자], 그리고 '--a' 는 [특수문자열] [영문자] 이므로 위와 같이 정렬되는 것이 맞다.

이 가설은 다음과 같은 실험(?)으로 검증할 수 있다.
사용자 삽입 이미지

'{'과 '}'은 아스키 코드 상으로는 'a' 보다 뒤에 있는 문자이지만 xp 파일명 정렬방식에서는 '--a' 보다 앞에 온다!


구글에서 검색을 해보니 windows xp에는 StrCmpLogicalW라고 하는 새로운 문자열 비교 API가 추가되었다고 한다. 초기에는 숫자가 아주 클 때에 문제가 생겼다는 이야기도 있는데 충분히 있을법한 버그이다. [숫자] 부분에는 정수만 들어오니까 마음 편히 int 로 변수를 선언하고 크기 비교를 하지 않았다면 오버플로우가 났겠지.
Posted by tuckoo
,