@@ -286,6 +286,26 @@ function ipToInt(ip: string): number {
286286 return ( parts [ 0 ] << 24 ) + ( parts [ 1 ] << 16 ) + ( parts [ 2 ] << 8 ) + parts [ 3 ] ;
287287}
288288
289+ /**
290+ * Check if IPv6 address is in range using string comparison
291+ */
292+ function isIPv6InRange ( ip : string , startIP : string , endIP : string ) : boolean {
293+ try {
294+ const ipAddr = new Address6 ( ip ) ;
295+ const startAddr = new Address6 ( startIP ) ;
296+ const endAddr = new Address6 ( endIP ) ;
297+
298+ // Use canonicalForm for consistent comparison
299+ const ipCanonical = ipAddr . canonicalForm ( ) ;
300+ const startCanonical = startAddr . canonicalForm ( ) ;
301+ const endCanonical = endAddr . canonicalForm ( ) ;
302+
303+ return ipCanonical >= startCanonical && ipCanonical <= endCanonical ;
304+ } catch ( e ) {
305+ return false ;
306+ }
307+ }
308+
289309/**
290310 * Find geolocation data for IP
291311 */
@@ -327,16 +347,10 @@ function findGeolocation(ip: string, version: IPVersion): NormalizedIPData['loca
327347 }
328348 }
329349 } else {
330- // For IPv6, use simple linear search (could be optimized)
331- const ipAddr = new Address6 ( ip ) ;
332-
350+ // For IPv6, use linear search with improved comparison
333351 for ( const record of cache ) {
334352 try {
335- const startAddr = new Address6 ( record . startIP ) ;
336- const endAddr = new Address6 ( record . endIP ) ;
337-
338- if ( ipAddr . bigInteger ( ) >= startAddr . bigInteger ( ) &&
339- ipAddr . bigInteger ( ) <= endAddr . bigInteger ( ) ) {
353+ if ( isIPv6InRange ( ip , record . startIP , record . endIP ) ) {
340354 return {
341355 country : record . country || undefined ,
342356 countryCode : record . countryCode || undefined ,
0 commit comments