[Delphi] bitmask를 이용한 IP 범위 얻어오기

Programming/Code 2011.05.19 댓글 Joshua95

(참고 링크: http://www.delphi3000.com/articles/article_3845.asp?SK= )

Delphi를 이용해서 '172.16.103.0/24' 형태로 Bitmask 를 포함하여 입력이 될 경우, 해당 Range의 처음값과 마지막 값으로 DB 쿼리를 만들고자 합니다. 그래서 다음의 함수를 만들었지요. 물론, 처음 DB 저장을 bigint 로 했다면 좀 덜 삽질을 했을터인데 전임자들이 IP 정보를 그냥 스트링으로 저장하는 바람에 괜한 고생입니다.

구글링을 통해서 IpToInt, IntToIp 함수를 따와서 원하는 procedure를 만들었습니다. 여튼 이넘의 IP 조작은 이래저래 필요한 경우가 많아요.

1) 일단 스트링으로 된 IP를 Int로 변환하기

// IP 스트링을 Int로 변환하는 함수
function IpToInt(const AIpAddress : string) : longword;
var Retvar,i,iShift : longword;
    sData,sSeg : string;
begin
  Retvar := 0;
  iShift := 24;
  sData := trim(AIpAddress);

  while sData <> '' do begin
    i := pos('.',sData);

    if i <> 0 then begin
      sSeg := copy(sData,1,i - 1);
      sData := copy(sData,i+1,length(sData));
    end
    else begin
      sSeg := sData;
      sData := '';
    end;

    Retvar := Retvar + (longword(StrToIntDef(sSeg,0)) shl iShift);
    dec(iShift,8);
  end;

  Result := Retvar;
end;

2) 1)번의 쌍으로 Int로 저장된 IP 주소를 스트링(예.xxx.xxx.xxx.xxx)으로 변환하기
// Integer IP 주소를 스티링으로 변환하기
function IntToIp(AIpValue : longword) : string;
var Retvar : string;
    iSeg,iShift,
    i,iMask : longword;
begin
  Retvar := '';
  iShift := 24;
  iMask := $FF000000;

  for i := 1 to 4 do begin
    iSeg := (AIpValue and iMask) shr iShift;
    Retvar := Retvar + IntToStr(iSeg);
    if i <> 4 then Retvar := Retvar + '.';
    iMask := iMask shr 8;
    dec(iShift,8);
  end;

  Result := Retvar;
end;

3) Bitmask 포함된 IP 스트링 (예. 172.16.10.0/24)를 이용한 IP 범위 얻어오기
해당 IP 범위 중 가장 작은 값과 가장 큰 값을 가져와서 DB 쿼리를 만들 때 사용하자.
// Bitmask 포함된 IP 스트링 (예. 172.16.10.0/24)를 이용한 IP 범위 얻어오기
procedure TForm1.GetIPRange(strIPRange : string; var iLowestIP, iHighestIP : LongWord);
var
    slToken : TStringList;
    iTargetIP, iBitmask : longword;
    iBitCount : integer;

begin
    iLowestIP := 0;
    iHighestIP := 0;

    try
        slToken := TStringList.Create;
        slToken.Delimiter := '/';
        slToken.DelimitedText := strIPRange;

        if(slToken.Count > 1) then
        begin
            try
              iTargetIP := IpToInt(slToken[0]);

              iBitCount := StrToIntDef(slToken[1], 0);
              if((iBitCount > 0) AND (iBitCount <= 32)) then
              begin
                  iBitmask := $FFFFFFFF SHL (32-iBitCount);

                  // get lowest ip
                  iLowestIP := iTargetIP AND iBitmask;

                  // get highest ip
                  iHighestIP := iTargetIP OR (NOT iBitmask);
               end;
            except
            end;

        end;
    finally
        slToken.Free;
    end;

end;

이상 끝!
- 2010.05.19 Joshua95

댓글