czdb
Version:
A javascript library for searching IP address-related data in a CZDB database
406 lines (395 loc) • 15.9 kB
TypeScript
declare class Cz88RandomAccessFile {
private fd;
private offset;
private currentPosition;
private alive;
constructor(filename: string, mode: string, offset: number);
seek(position: number): void;
read(buffer: Buffer, length: number): number;
readFully(buffer: Buffer, off?: number, len?: number): void;
write(buffer: Buffer, length: number): number;
length(): number;
close(): void;
}
declare class DecryptedBlock {
private clientId;
private expirationDate;
private randomSize;
constructor();
/**
* Gets the client ID.
* @return The client ID.
*/
getClientId(): number;
/**
* Sets the client ID.
* @param clientId The client ID to set.
*/
setClientId(clientId: number): void;
/**
* Gets the expiration date.
* @return The expiration date.
*/
getExpirationDate(): number;
/**
* Sets the expiration date.
* @param expirationDate The expiration date to set.
*/
setExpirationDate(expirationDate: number): void;
/**
* Gets the size of the random bytes.
* This method returns the size of the random bytes that are used in the encryption process.
* The random bytes size is crucial for ensuring the uniqueness and security of the encryption.
*
* @return The size of the random bytes.
*/
getRandomSize(): number;
/**
* Sets the size of the random bytes.
* This method allows setting the size of the random bytes that are to be used in the encryption process.
* Adjusting the size of the random bytes can impact the security and performance of the encryption.
*
* @param randomSize The size of the random bytes to set.
*/
setRandomSize(randomSize: number): void;
/**
* Serializes the DecryptedBlock instance into a byte array.
* The array is structured as follows: the first 4 bytes contain the client ID and expiration date,
* the next 4 bytes contain the start pointer, and the last 8 bytes are reserved and initialized to 0.
* @return A 16-byte array representing the serialized DecryptedBlock instance.
*/
toBytes(): Buffer;
/**
* Encrypts the provided byte array using AES encryption with a specified key.
* The key is expected to be a base64 encoded string representing the AES key.
* @param data The byte array to encrypt.
* @param key The base64 encoded string representing the AES key.
* @return The encrypted byte array.
* @throws Exception If an error occurs during encryption.
*/
encrypt(data: Buffer, key: string): Buffer;
toEncryptedBytes(key: string): Buffer;
static decrypt(key: string, encryptedBytes: Buffer): DecryptedBlock;
}
declare class HyperHeaderBlock {
static readonly HEADER_SIZE = 12;
protected version: number;
protected clientId: number;
protected encryptedBlockSize: number;
protected encryptedData: Buffer;
protected decryptedBlock: DecryptedBlock;
constructor();
/**
* Gets the version of the HyperHeaderBlock.
* @return The version of the HyperHeaderBlock.
*/
getVersion(): number;
/**
* Sets the version of the HyperHeaderBlock.
* @param version The version to set.
*/
setVersion(version: number): void;
/**
* Gets the client ID of the HyperHeaderBlock.
* @return The client ID of the HyperHeaderBlock.
*/
getClientId(): number;
/**
* Sets the client ID of the HyperHeaderBlock.
* @param clientId The client ID to set.
*/
setClientId(clientId: number): void;
/**
* Gets the size of the encrypted data block.
* @return The size of the encrypted data block.
*/
getEncryptedBlockSize(): number;
/**
* Sets the size of the encrypted data block.
* @param encryptedBlockSize The size of the encrypted data block to set.
*/
setEncryptedBlockSize(encryptedBlockSize: number): void;
getEncryptedData(): Buffer;
setEncryptedData(encryptedData: Buffer): void;
getDecryptedBlock(): DecryptedBlock;
setDecryptedBlock(decryptedBlock: DecryptedBlock): void;
/**
* Converts the HyperHeaderBlock instance into a byte array.
* This method serializes the HyperHeaderBlock instance into a byte array, which can be used for storage or transmission.
* The byte array is structured as follows:
* - The first 4 bytes represent the version of the HyperHeaderBlock.
* - The next 4 bytes represent the client ID.
* - The following 4 bytes represent the length of the encrypted data.
*
* @return A byte array representing the serialized HyperHeaderBlock instance.
*/
toBytes(): Buffer;
/**
* Deserializes a HyperHeaderBlock instance from a 12 length byte array.
* This method takes a byte array and constructs a HyperHeaderBlock instance from it.
* The byte array is expected to be structured as follows:
* - The first 4 bytes represent the version of the HyperHeaderBlock.
* - The next 4 bytes represent the client ID.
* - The following 4 bytes represent the length of the encrypted data.
*
* @param bytes The byte array to deserialize.
* @return A HyperHeaderBlock instance constructed from the byte array.
*/
static fromBytes(bytes: Buffer): HyperHeaderBlock;
/**
* Returns the total size of the HyperHeaderBlock.
* The size is calculated as the sum of the following:
* - The size of the header (12 bytes)
* - The size of the encrypted data block
* - The size of the random bytes
*
* @return The total size of the HyperHeaderBlock in bytes.
*/
getHeaderSize(): number;
}
declare class HyperHeaderDecoder {
/**
* Reads data from an InputStream and deserializes it into a HyperHeaderBlock.
* The method first reads the header bytes and extracts the version, clientId, and encryptedBlockSize.
* Then it reads the encrypted bytes and decrypts them into a DecryptedBlock.
* It checks if the clientId and expirationDate in the DecryptedBlock match the clientId and version in the HyperHeaderBlock.
* If they do not match, it throws an exception.
* If the expirationDate in the DecryptedBlock is less than the current date, it throws an exception.
* Finally, it creates a new HyperHeaderBlock with the read and decrypted data and returns it.
*
* @param is The InputStream to read data from.
* @param key The key used for decryption.
* @return A HyperHeaderBlock deserialized from the read data.
* @throws Exception If an error occurs during the decryption process, or if the clientId or expirationDate do not match the expected values.
*/
static decrypt(dbFilePath: string, key: string): HyperHeaderBlock;
}
/**
* The DbType enum represents the different types of database types available in the application.
* It includes IPV4 and IPV6 types.
*/
declare enum DbType {
/**
* Represents the IPV4 type.
* This type is used when the database is storing data related to IPV4 addresses.
*/
IPV4 = "IPV4",
/**
* Represents the IPV6 type.
* This type is used when the database is storing data related to IPV6 addresses.
*/
IPV6 = "IPV6"
}
/**
* The QueryType enum represents the different types of query modes available in the application.
* It includes MEMORY, BINARY, and BTREE modes.
*/
declare enum QueryType {
/**
* Represents the MEMORY mode.
* This mode is thread-safe and stores the data in memory.
*/
MEMORY = "MEMORY",
/**
* Represents the BTREE mode.
* This mode uses a B-tree data structure for querying.
* It is not thread-safe. Different threads can use different query objects.
* In case of high concurrency, it may lead to too many open files error.
* In such cases, either increase the maximum allowed open files in the kernel (fs.file-max) or use the MEMORY mode.
*/
BTREE = "BTREE"
}
declare class IndexBlock {
private startIp;
private endIp;
private dataPtr;
private dataLen;
private dbType;
/**
* Constructor for the IndexBlock class.
* It initializes the start IP, end IP, data pointer, and data length with the provided values.
*
* @param startIp The start IP address of the range that the data block covers.
* @param endIp The end IP address of the range that the data block covers.
* @param dataPtr The pointer to the data block in the database.
* @param dataLen The length of the data block in bytes.
* @param dbType The type of the database (IPV4 or IPV6).
*/
constructor(startIp: Buffer, endIp: Buffer, dataPtr: number, dataLen: number, dbType: DbType);
getStartIp(): Buffer;
setStartIp(startIp: Buffer): IndexBlock;
getEndIp(): Buffer;
setEndIp(endIp: Buffer): IndexBlock;
getDataPtr(): number;
setDataPtr(dataPtr: number): IndexBlock;
getDataLen(): number;
setDataLen(dataLen: number): IndexBlock;
static getIndexBlockLength(dbType: DbType): number;
/**
* Returns a byte array representing the index block.
* The byte array is structured as follows:
* +------------+-----------+-----------+
* | 4/16 bytes | 4/16 bytes | 4 bytes | 1 byte |
* +------------+-----------+-----------+
* start ip end ip data ptr len
*
* @return A byte array representing the index block.
*/
getBytes(): Buffer;
}
declare class Decryptor {
private keyBytes;
constructor(key: string);
decrypt(data: Buffer): Buffer;
}
declare class DataBlock {
private region;
private dataPtr;
constructor(region: Buffer, dataPtr: number);
/**
* Returns the region of this data block.
*
* @return the region of this data block
*/
getRegion(geoMapData: Buffer | null, columnSelection: number): string | null;
/**
* Sets the region of this data block to the specified value.
*
* @param region the new region
* @return this data block
*/
setRegion(region: Buffer): DataBlock;
/**
* Returns the data pointer of this data block.
*
* @return the data pointer of this data block
*/
getDataPtr(): number;
/**
* Sets the data pointer of this data block to the specified value.
*
* @param dataPtr the new data pointer
* @return this data block
*/
setDataPtr(dataPtr: number): DataBlock;
private unpack;
}
declare class DbSearcher {
private dbType;
private dbVersion;
private ipBytesLength;
private queryType;
private totalHeaderBlockSize;
/**
* Handler for accessing the database file.
* It is used to read from and write to the file.
*/
private raf;
/**
* These are used only for B-tree search.
* HeaderSip is a 2D byte array representing the start IP of each index block.
* HeaderPtr is an integer array representing the data pointer of each index block.
* headerLength is the number of index blocks in the header.
*/
private HeaderSip;
private HeaderPtr;
private headerLength;
/**
* These are used for memory and binary search.
* firstIndexPtr is the pointer to the first index block.
* lastIndexPtr is the pointer to the last index block.
* totalIndexBlocks is the total number of index blocks.
*/
private firstIndexPtr;
private totalIndexBlocks;
private dbBinStr;
private columnSelection;
private geoMapData;
/**
* Constructor for DbSearcher class.
* Initializes the DbSearcher instance based on the provided database file, query type, and key.
* Depending on the query type, it calls the appropriate initialization method.
*
* @param dbFilePath The path to the database file.
* @param queryType The type of the query (MEMORY, BTREE).
* @param key The key used for decrypting the header block of the database file.
*/
constructor(dbFilePath: string, queryType: QueryType, key: string);
private loadGeoSetting;
/**
* Initializes the DbSearcher instance for memory search.
* Reads the entire database file into memory and then initializes the parameters for memory or binary search.
*/
private initializeForMemorySearch;
private initMemoryOrBinaryModeParam;
private initBtreeModeParam;
private initHeaderBlock;
/**
* This method is used to search for a region in the database based on the provided IP address.
* It supports three types of search algorithms: memory, binary, and B-tree.
* The type of the search algorithm is determined by the queryType attribute of the DbSearcher instance.
* The method first converts the IP address to a byte array, then performs the search based on the query type.
* If the search is successful, it returns the region of the found data block.
* If the search is unsuccessful, it returns null.
*
* @param ip The IP address to search for. It is a string in the standard IP address format.
* @return The region of the found data block if the search is successful, null otherwise.
*/
search(ip: string): string | null;
getVersion(): number;
/**
* This method performs a memory search to find a data block in the database based on the provided IP address.
* It uses a binary search algorithm to search the index blocks and find the data.
* If the search is successful, it returns the data block containing the region and the data pointer.
* If the search is unsuccessful, it returns null.
*
* @param ip The IP address to search for. It is a byte array representing the IP address.
* @return The data block containing the region and the data pointer if the search is successful, null otherwise.
*/
private memorySearch;
searchInHeader(ip: Buffer): number[];
/**
* get the region with a int ip address with b-tree algorithm
*
* @param ip
* @throws IOException
*/
private bTreeSearch;
/**
* get db type
*
* @return
*/
getDbType(): DbType;
/**
* get query type
*
* @return
*/
getQueryType(): QueryType;
/**
* close the db
*
* @throws IOException
*/
close(): void;
getIpBytes(ip: string): Buffer;
/**
* This method compares two byte arrays up to a specified length.
* It is used to compare IP addresses in byte array format.
* The comparison is done byte by byte, and the method returns as soon as a difference is found.
* If the bytes at the current position in both arrays are positive or negative, the method compares their values.
* If the bytes at the current position in both arrays have different signs, the method considers the negative byte as larger.
* If one of the bytes at the current position is zero and the other is not, the method considers the zero byte as smaller.
* If the method has compared all bytes up to the specified length and found no differences, it compares the lengths of the byte arrays.
* If the lengths are equal, the byte arrays are considered equal.
* If one byte array is longer than the other, it is considered larger.
*
* @param bytes1 The first byte array to compare. It represents an IP address.
* @param bytes2 The second byte array to compare. It represents an IP address.
* @param length The number of bytes to compare in each byte array.
* @return A negative integer if the first byte array is less than the second, zero if they are equal, or a positive integer if the first byte array is greater than the second.
*/
private compareBytes;
}
export { Cz88RandomAccessFile, DataBlock, DbType, Decryptor, HyperHeaderDecoder, IndexBlock, QueryType, DbSearcher as default };