ip 주소를 sql에서 다루어야 할 일이 있습니다. 오늘은, ip address를 unsigned integer로 바꾸는 함수와 unsigned integer를 다시 ip addr로 바꾸는 함수를 알아보도록 하겠습니다. 당연하게도, ipv4인 경우이고요. ipv6인 경우는 따로 있습니다.

 


 inet_aton과 inet_ntoa는 크게 어렵지 않습니다. 단순하게 해석해 봅시다. a는 Address의 약자일 겁니다. 그리고 n은 Number일 거고요. 중간에 to는 AtoB할 때 그 to가 맞습니다. 즉, A에서 N으로 변환하는 함수가 aton이고, N에서 A로 변환하는 함수가 ntoa인 셈입니다.

 

 ipv4 시스템에서, 255.255.255.255까지 나올 수 있습니다. 이 값을 numeric address로 바꾸면 4294967295입니다. 당연하게도, 링크에 보시면 inet_aton으로 generate 되는 value를 저장해야 할 경우, 다음과 같이 하라고 되어 있습니다.

 

 왜냐하면, signed int로 저장하는 경우 128.0.0.0부터 255.255.255.255까지는 제대로 저장을 하지 못하기 때문이라고 되어 있는데요. 오버플로우 때문입니다. 부호있는 4byte int에서 2147483648을 표현할 수 없어요. 부호가 없으면 모를까.

 

 

 두 함수를 간략하게 요약하면 위 그림과 같습니다. 192.168.0.2 꼴의 ip address를 3232235522로 바꾸는 함수가 inet_aton이고, 수 3232235522를 192.168.0.2로 바꾸는 것이 inet_ntoa입니다. 예제를 보면 확실할 듯 하니 예제만 간단하게 보겠습니다.

 


 먼저, 쿼리 select inet_aton("192.168.0.3")을 입력하였습니다. 결과가 어떻게 나올까요? A.B.C.D 꼴로 입력했다면, 256^3에 A를 곱한 값을 a, 256^2에 B를 곱한 값을 b, 256에 C를 곱한 값을 c, 1에 D를 곱한 값을 d라고 해 보겠습니다. 이 때, a + b + c + d의 값을 리턴합니다.

 

 

 192.168.0.3을 aton을 했을 때, 3232235523을 돌려주었습니다.

 

 

 3232235523을 계산기의 프로그래머 모드로 보면 위와 같습니다. 여기서 BIN을 8자리 단위로 끊어서 적어보도록 하겠습니다.

 

 

 11000000 10101000 00000000 00000011입니다. 이들을 2진수로 바꾸면 192, 168, 0, 3임을 알 수 있습니다. 이제, 역방향으로 밖꿔 보겠습니다.

 


 select inet_ntoa(4242000000) 쿼리를 생각해 보겠습니다.

 

 이것은 결과가 어떻게 나올까요? 생각보다 까다로운데요. 먼저 4242000000을 2진수로 바꿔 보겠습니다.

 

 

 그러면 11111100 11010111 11001000 10000000 이렇게 나옵니다. 대충 8자리씩 끊은 것입니다. 이들을 각각 10진수로 바꿔 보겠습니다. 11111100은 10진수로 252, 11010111은 10진수로 215, 11001000은 10진수로 200, 10000000은 10진수로 128입니다.

 

 

 이 상황을 그림으로 그려보면 위와 같습니다. 따라서, 4242000000을 우리가 알고 있는 A.B.C.D로 바꾼 결과는 아래와 같습니다.

 

 

 252.215.200.128. 4byte unsigned integer로만 준다면 0.0.0.0부터 255.255.255.255를 모두 표현할 수 있다는 것과 aton과 ntoa만 잘 이용하면 ip 주소를 다루는 것도 그렇게 어렵지 않아 보입니다.