2010-09-08 2 views
8

Nous utilisons un champ binaire (16) pour stocker les adresses IP. Nous faisons cela car il peut contenir à la fois des adresses IPv4 et IPv6 et est facilement utilisé avec la classe .Net IPAddress.Perfectionnement de la conversion de chaîne binaire SQL en adresse IP

Toutefois, j'ai créé la fonction SQL suivante pour convertir l'adresse binaire en chaîne d'adresse IP à des fins de génération de rapports.

CREATE FUNCTION fn_ConvertBinaryIPAddressToString 
(
    @binaryIP binary(16) 
) 
RETURNS nvarchar(39) 
AS 
BEGIN 
    DECLARE @ipAsString nvarchar(39) 

    -- Is IPv4 
    IF (substring(@binaryIP, 5, 1) = 0x00) <-- Is there a better way? 
    BEGIN 

     SELECT @ipAsString = CAST(CAST(substring(@binaryIP, 1, 1) AS int) AS nvarchar(3)) + '.' + 
     CAST(CAST(substring(@binaryIP, 2, 1) AS int) AS nvarchar(3)) + '.' + 
     CAST(CAST(substring(@binaryIP, 3, 1) AS int) AS nvarchar(3)) + '.' + 
     CAST(CAST(substring(@binaryIP, 4, 1) AS int) AS nvarchar(3)) 

    END 
    ELSE 
    BEGIN 
    -- Is IPv6 
     -- taken and modified from http://support.microsoft.com/kb/104829 
     DECLARE @i int 
     DECLARE @length int 
     DECLARE @hexstring char(16) 

     SELECT @ipAsString = '' 
     SELECT @i = 1 
     SELECT @length = 16 
     SELECT @hexstring = 'ABCDEF' 

     WHILE (@i <= @length) 
     BEGIN 
      DECLARE @tempint int 
      DECLARE @firstint int 
      DECLARE @secondint int 

      SELECT @tempint = convert(int, substring(@binaryIP,@i,1)) 
      SELECT @firstint = floor(@tempint/16) 
      SELECT @secondint = @tempint - (@firstint*16) 

      SELECT @ipAsString = @ipAsString + substring(@hexstring, @firstint+1, 1) + substring(@hexstring, @secondint+1, 1) 

      IF (@i % 2 = 0) 
       SELECT @ipAsString = @ipAsString + ':' 

      SELECT @i = @i + 1 
     END 
    END 

    -- Return the result of the function 
    RETURN @ipAsString 

END 
GO 

Au moment où le 5 octet est 0, je suppose qu'il s'agit d'une adresse IPv4. Est-ce une hypothèse sûre? Est-il préférable de vérifier tous les octets restants pour les zéros ou existe-t-il un meilleur moyen?

EDIT enlevé coulé inutile

Répondre

5

Je dirais que vous devriez être stocker la famille d'adresse aussi, que ce soit codé dans votre tableau d'octets ou une colonne séparée. Si vous transmettez 16 octets au constructeur IPAddress, il sera construit en tant qu'adresse IPv6, vous aurez donc besoin de vérifier votre code pour déterminer la famille d'adresses. Il semblerait beaucoup plus facile (et ne repose pas sur des hypothèses sur les octets d'une adresse IPv6) de garder cette information directement.

Ou utilisez un varbinary (16), que vous pouvez ensuite vérifier la longueur de (longueur = 4 => Adresse IPv4)

+0

grand merci des conseils. – Magpie