티스토리 뷰

728x90
반응형

ASCII(str)

문자열의 가장 왼쪽에 있는 문자의 정수 값을 반환합니다. 만약 빈 문자열이라면 0 을 반환하고, 문자열이 NULL이라면 NULL을 반환합니다. ASCII() 함수는 8bit 문자에 한해서 기능합니다.

mysql> SELECT ASCII('4');
+------------+
| ASCII('4') |
+------------+
|         52 |
+------------+
1 row in set (0.00 sec)

mysql> SELECT ASCII(4);
+----------+
| ASCII(4) |
+----------+
|       52 |
+----------+
1 row in set (0.00 sec)

mysql> SELECT ASCII('ABCD');
+---------------+
| ASCII('ABCD') |
+---------------+
|            65 |
+---------------+
1 row in set (0.00 sec)​

ASCII() 함수는 ORD() 함수와 유사하면서도 다릅니다.

 

ORD(str)

만약 문자열 중 제일 왼쪽에 있는 문자가 멀티바이트(Multibyte) 문자라면, 특정 공식을 이용해 계산한 숫자를 반환합니다. 공식은 다음과 같습니다.

  (첫번째 byte code)
+ (두번째 byte code * 256)
+ (세번째 byte code * 256^2) ...​

 

예를 들어 UTF-8 에서 '가' 라는 문자는 11101010 10110000 10000000 로 표현됩니다.
ORD() 함수는 해당 코드를 10진수로 변환하여 15380608로 출력합니다.
만약 ASCII() 함수라면 제일 왼쪽에서 8bit(1byte)만큼만 정수로 변환하여 234(=11101010)로 출력할 것입니다.

ORD() 함수도 ASCII() 함수처럼 멀티바이트(Multibyte) 문자가 아닌 값을 인자로 받는다면, ASCII() 함수와 동일한 기능을 하게 됩니다.

혹시 만약에 ORD('가') 의 결과가 15380608 이 아니라 45217 이 나온다면 MySQL 인코딩이 EUC-KR 로 설정되어 있어서 그럴 것입니다. 만약 status 라는 명령어를 쳤을 때 아래와 같이 Client characterset 이 euckr 라고 나온다면, UTF-8 이 아닌 EUC-KR 인코딩으로 설정되어 있는 것입니다.

mysql> status
--------------
mysql  Ver 8.0.22 for Win64 on x86_64 (MySQL Community Server - GPL)

Connection id:          26
Current database:
Current user:           root@localhost
SSL:                    Cipher in use is TLS_AES_256_GCM_SHA384
Using delimiter:        ;
Server version:         8.0.22 MySQL Community Server - GPL
Protocol version:       10
Connection:             localhost via TCP/IP
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    euckr
Conn.  characterset:    euckr
TCP port:               3306
Binary data as:         Hexadecimal
Uptime:                 7 days 1 hour 31 min 39 sec

Threads: 2  Questions: 34  Slow queries: 0  Opens: 140  Flush tables: 3  Open tables: 61  Queries per second avg: 0.000
--------------

 

status 명령어 말고도 현재 MySQL 인코딩을 유추할 수 있는 방법으로는 BIT_LENGTH() 함수를 사용하는 것입니다.
BIT_LENGTH() 함수는 문자열의 비트크기를 반환하는데요. '가'라는 문자의 비트 수가 16bit(2byte)이라면 EUC-KR이고, 24bit(3byte)라면 UTF-8인 것을 알 수 있습니다.

mysql> SELECT BIT_LENGTH('가');
+------------------+
| BIT_LENGTH('가') |
+------------------+
|               16 |
+------------------+
1 row in set (0.00 sec)

mysql> SELECT BIT_LENGTH('가');
+------------------+
| BIT_LENGTH('가') |
+------------------+
|               24 |
+------------------+
1 row in set (0.00 sec)

 

이후 SQL Injection 같은 공격을 시도해볼 때 해당 값이 한글 또는 다른 유니코드로 된 것인지 아니면 영문자나 일반적인 숫자나 기호로 이루어져있는 지 확인해보기 유용할 것으로 보이는 함수입니다. 다만, _(언더바)가 필터링되지 않는 환경에서 사용가능할 것으로 보입니다.

728x90
반응형
댓글