C # Read the QQ pure IP database QQWry. Dat code

Source: Internet
Author: User

Pure qq ip database

Copy codeThe Code is as follows: using System;
Using System. Collections. Generic;
Using System. Text;
Using System. IO;
Using System. Web;
Using System. Configuration;

Namespace BLL
{
Public class IPLocationSearch
{
Private static readonly QQWry qq = new QQWry (ConfigurationManager. etettings ["ip"] + "qqwry. dat ");

Public static IPLocation GetIPLocation (string ip)
{
Return qq. SearchIPLocation (ip );
}
}

/*
Usage:

Example:
BDQQ. Data. QQWry qq = new BDQQ. Data. QQWry ("d: \ QQWry. Dat ");
BDQQ. Data. IPLocation ip = qq. SearchIPLocation ("127.0.0.1"); // Add an ip address here
Console. WriteLine (ip. country); // country
Console. WriteLine (ip. area); // Region
*/

// The following is a class file
// Rewrite it based on LumaQQ.

/**/
/// <Summary>
/// Summary of QQWry.
/// </Summary>
Public class QQWry
{
// The first Mode
# Region first Mode
/**/
/// <Summary>
/// The first Mode
/// </Summary>
# Endregion
Private const byte REDIRECT_MODE_1 = 0x01;

// Second mode
# Region second mode
/**/
/// <Summary>
/// Second mode
/// </Summary>
# Endregion
Private const byte REDIRECT_MODE_2 = 0x02;

// The length of each record
# Region length of each record
/**/
/// <Summary>
/// The length of each record
/// </Summary>
# Endregion
Private const int IP_RECORD_LENGTH = 7;

// Database file
# Region database file
/**/
/// <Summary>
/// File object
/// </Summary>
# Endregion
Private FileStream ipFile;

Private const string unCountry = "unknown country ";
Private const string unArea = "Unknown Region ";

// Start position of the Index
# Region index start position
/**/
/// <Summary>
/// Start position of the Index
/// </Summary>
# Endregion
Private long ipBegin;

// Index end position
# Region index end position
/**/
/// <Summary>
/// Index end position
/// </Summary>
# Endregion
Private long ipEnd;

// Ip address object
# Region IP address object
/**/
/// <Summary>
/// IP object
/// </Summary>
# Endregion
Private IPLocation loc;

// Store text content
# Region stores text content
/**/
/// <Summary>
/// Store text content
/// </Summary>
# Endregion
Private byte [] buf;

// Store 3 bytes
# Region stores 3 bytes
/**/
/// <Summary>
/// Store 3 bytes
/// </Summary>
# Endregion
Private byte [] b3;

// Store 4 bytes
# Region stores 4 bytes
/**/
/// <Summary>
/// Store 4-byte IP addresses
/// </Summary>
# Endregion
Private byte [] b4;

// Constructor
# Region Constructor
/**/
/// <Summary>
/// Constructor
/// </Summary>
/// <Param name = "ipfile"> absolute path of the IP database file </param>
# Endregion
Public QQWry (string ipfile)
{

Buf = new byte [100];
B3 = new byte [3];
B4 = new byte [4];
Try
{
IpFile = new FileStream (ipfile, FileMode. Open );
}
Catch (Exception ex)
{
Throw new Exception (ex. Message );
}
IpBegin = readLong4 (0 );
IpEnd = readLong4 (4 );
Loc = new IPLocation ();
}

// Search by IP Address
# Region search by IP Address
/**/
/// <Summary>
/// Search for IP addresses
/// </Summary>
/// <Param name = "ip"> </param>
/// <Returns> </returns>
# Endregion
Public IPLocation SearchIPLocation (string ip)
{
// Convert the character IP address to byte
String [] ipSp = ip. Split ('.');
If (ipSp. Length! = 4)
{
Throw new ArgumentOutOfRangeException ("it is not a legal IP address! ");
}
Byte [] IP = new byte [4];
For (int I = 0; I <IP. Length; I ++)
{
IP [I] = (byte) (Int32.Parse (ipSp [I]) & 0xFF );
}

IPLocation local = null;
Long offset = locateIP (IP );

If (offset! =-1)
{
Local = getIPLocation (offset );
}

If (local = null)
{
Local = new IPLocation ();
Local. area = unArea;
Local. country = unCountry;
}
Return local;
}

// Obtain specific information
# Region
/**/
/// <Summary>
/// Obtain specific information
/// </Summary>
/// <Param name = "offset"> </param>
/// <Returns> </returns>
# Endregion
Private IPLocation getIPLocation (long offset)
{
IpFile. Position = offset + 4;
// Read the first byte to determine whether it is a flag byte
Byte one = (byte) ipFile. ReadByte ();
If (one = REDIRECT_MODE_1)
{
// The first Mode
// Read the country offset
Long countryOffset = readLong3 ();
// Go to the offset
IpFile. Position = countryOffset;
// Check the flag byte again
Byte B = (byte) ipFile. ReadByte ();
If (B = REDIRECT_MODE_2)
{
Loc. country = readString (readLong3 ());
IpFile. Position = countryOffset + 4;
}
Else
Loc. country = readString (countryOffset );

// Read the region flag
Loc. area = readArea (ipFile. Position );

}
Else if (one = REDIRECT_MODE_2)
{
// Second mode
Loc. country = readString (readLong3 ());
Loc. area = readArea (offset + 8 );
}
Else
{
// Normal Mode
Loc. country = readString (-- ipFile. Position );
Loc. area = readString (ipFile. Position );
}
Return loc;
}

// Obtain region information
# Region obtain region information
/**/
/// <Summary>
/// Read the region name
/// </Summary>
/// <Param name = "offset"> </param>
/// <Returns> </returns>
# Endregion
Private string readArea (long offset)
{
IpFile. Position = offset;
Byte one = (byte) ipFile. ReadByte ();
If (one = REDIRECT_MODE_1 | one = REDIRECT_MODE_2)
{
Long areaOffset = readLong3 (offset + 1 );
If (areaOffset = 0)
Return unArea;
Else
{
Return readString (areaOffset );
}
}
Else
{
Return readString (offset );
}
}

// Read the string
# Region read string
/**/
/// <Summary>
/// Read the string
/// </Summary>
/// <Param name = "offset"> </param>
/// <Returns> </returns>
# Endregion
Private string readString (long offset)
{
IpFile. Position = offset;
Int I = 0;
For (I = 0, buf [I] = (byte) ipFile. ReadByte (); buf [I]! = (Byte) (0); buf [++ I] = (byte) ipFile. ReadByte ());

If (I> 0)
Return Encoding. Default. GetString (buf, 0, I );
Else
Return "";
}

// Find the absolute offset of the IP address
# Region: Find the absolute offset of the IP address
/**/
/// <Summary>
/// Find the absolute offset of the IP address
/// </Summary>
/// <Param name = "ip"> </param>
/// <Returns> </returns>
# Endregion
Private long locateIP (byte [] ip)
{
Long m = 0;
Int r;

// Compare the first IP Address
ReadIP (ipBegin, b4 );
R = compareIP (ip, b4 );
If (r = 0)
Return ipBegin;
Else if (r <0)
Return-1;
// Start Binary Search
For (long I = ipBegin, j = ipEnd; I <j ;)
{
M = this. getMiddleOffset (I, j );
ReadIP (m, b4 );
R = compareIP (ip, b4 );
If (r> 0)
I = m;
Else if (r <0)
{
If (m = j)
{
J-= IP_RECORD_LENGTH;
M = j;
}
Else
{
J = m;
}
}
Else
Return readLong3 (m + 4 );
}
M = readLong3 (m + 4 );
ReadIP (m, b4 );
R = compareIP (ip, b4 );
If (r <= 0)
Return m;
Else
Return-1;
}

// Read the 4-byte IP Address
# Region read 4-byte IP Address
/**/
/// <Summary>
/// Read four bytes from the current location. These four bytes are IP addresses.
/// </Summary>
/// <Param name = "offset"> </param>
/// <Param name = "ip"> </param>
# Endregion
Private void readIP (long offset, byte [] ip)
{
IpFile. Position = offset;
IpFile. Read (ip, 0, ip. Length );
Byte tmp = ip [0];
Ip [0] = ip [3];
Ip [3] = tmp;
Tmp = ip [1];
Ip [1] = ip [2];
Ip [2] = tmp;
}

// Compare whether the IP address is the same
# Check whether the IP address of region is the same
/**/
/// <Summary>
/// Compare whether the IP address is the same
/// </Summary>
/// <Param name = "ip"> </param>
/// <Param name = "beginIP"> </param>
/// <Returns> 0: equal, 1: ip address greater than beginIP,-1: less than </returns>
# Endregion
Private int compareIP (byte [] ip, byte [] beginIP)
{
For (int I = 0; I <4; I ++)
{
Int r = compareByte (ip [I], beginIP [I]);
If (r! = 0)
Return r;
}
Return 0;
}

// Compare whether two bytes are equal
# Region compares two bytes for Equality
/**/
/// <Summary>
/// Compare whether two bytes are equal
/// </Summary>
/// <Param name = "bsrc"> </param>
/// <Param name = "bdst"> </param>
/// <Returns> </returns>
# Endregion
Private int compareByte (byte bsrc, byte bdst)
{
If (bsrc & 0xFF)> (bdst & 0xFF ))
Return 1;
Else if (bsrc ^ bdst) = 0)
Return 0;
Else
Return-1;
}

// Read 4 bytes according to the current position
# Region reads 4 bytes from the current location
/**/
/// <Summary>
/// Read 4 bytes from the current position and convert it to a long integer
/// </Summary>
/// <Param name = "offset"> </param>
/// <Returns> </returns>
# Endregion
Private long readLong4 (long offset)
{
Long ret = 0;
IpFile. Position = offset;
Ret | = (ipFile. ReadByte () & 0xFF );
Ret | = (ipFile. ReadByte () <8) & 0xFF00 );
Ret | = (ipFile. ReadByte () <16) & 0xFF0000 );
Ret | = (ipFile. ReadByte () <24) & 0xFF000000 );
Return ret;
}

// Read 3 bytes based on the current location
# Region reads 3 bytes based on the current location
/**/
/// <Summary>
/// Read 3 bytes based on the current location
/// </Summary>
/// <Param name = "offset"> </param>
/// <Returns> </returns>
# Endregion
Private long readLong3 (long offset)
{
Long ret = 0;
IpFile. Position = offset;
Ret | = (ipFile. ReadByte () & 0xFF );
Ret | = (ipFile. ReadByte () <8) & 0xFF00 );
Ret | = (ipFile. ReadByte () <16) & 0xFF0000 );
Return ret;
}

// Read 3 bytes from the current location
# Region reads 3 bytes from the current location
/**/
/// <Summary>
/// Read 3 bytes from the current location
/// </Summary>
/// <Returns> </returns>
# Endregion
Private long readLong3 ()
{
Long ret = 0;
Ret | = (ipFile. ReadByte () & 0xFF );
Ret | = (ipFile. ReadByte () <8) & 0xFF00 );
Ret | = (ipFile. ReadByte () <16) & 0xFF0000 );
Return ret;
}

// Get the offset between begin and end
# Region obtains the offset between begin and end.
/**/
/// <Summary>
/// Get the offset between begin and end
/// </Summary>
/// <Param name = "begin"> </param>
/// <Param name = "end"> </param>
/// <Returns> </returns>
# Endregion
Private long getMiddleOffset (long begin, long end)
{
Long records = (end-begin)/IP_RECORD_LENGTH;
Records> = 1;
If (records = 0)
Records = 1;
Return begin + records * IP_RECORD_LENGTH;
}
} // Class QQWry

Public class IPLocation
{
Public String country;
Public String area;

Public IPLocation ()
{
Country = area = "";
}

Public IPLocation getCopy ()
{
IPLocation ret = new IPLocation ();
Ret. country = country;
Ret. area = area;
Return ret;
}
}
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.