web-dev-qa-db-fra.com

Convertir un entier en hex et hex en un entier

Donc, cette requête fonctionne (où signal_data est une colonne) dans Sybase mais ne fonctionne pas dans Microsoft SQL Server:

HEXTOINT(SUBSTRING((INTTOHEX(signal_data)),5,2)) as Signal

Je l'ai aussi dans Excel (où A1 contient la valeur):

=HEX2DEC(LEFT(DEC2HEX(A1),LEN(DEC2HEX(A1))-2))

Est-ce que quelqu'un sait comment je le ferais dans SQL Server?

71
Nick Sinas

Convertir INT en hex:

SELECT CONVERT(VARBINARY(8), 16777215)

Convertir l'hex en INT:

SELECT CONVERT(INT, 0xFFFFFF)

Mise à jour 2015-03-16

L'exemple ci-dessus présente la limitation qu'il ne fonctionne que lorsque la valeur HEX est donnée sous forme de littéral entier. Pour être complet, si la valeur à convertir est une chaîne hexadécimale (telle que celle trouvée dans une colonne varchar), utilisez:

-- If the '0x' marker is present:
SELECT CONVERT(INT, CONVERT(VARBINARY, '0x1FFFFF', 1))

-- If the '0x' marker is NOT present:
SELECT CONVERT(INT, CONVERT(VARBINARY, '1FFFFF', 2))

Remarque: La chaîne doit contenir un nombre pair de chiffres hexadécimaux. Un nombre impair de chiffres donnera une erreur.

Plus de détails peuvent être trouvés dans la section "Styles binaires" de CAST et CONVERT (Transact-SQL) . Je pense que SQL Server 2008 ou version ultérieure est requis.

103
Bill Karwin

En fait, la fonction intégrée s'appelle master.dbo.fn_varbintohexstr.

Donc, par exemple:

SELECT 100, master.dbo.fn_varbintohexstr(100)

Vous donne

100 0x00000064

43
justinpitts

SQL Server équivalent aux fonctions DEC2HEX, HEX2DEC basées sur des chaînes d'Excel:

--Convert INT to hex string:
PRINT CONVERT(VARCHAR(8),CONVERT(VARBINARY(4), 16777215),2) --DEC2HEX

--Convert hex string to INT:
PRINT CONVERT(INT,CONVERT(VARBINARY(4),'00FFFFFF',2)) --HEX2DEC
25
Kip Bryan

Il est possible d'utiliser la fonction FORMAT disponible sur SQL Server 2012 et supérieur 

select FORMAT(10,'x2')

Résulte en:

0a
7
wndproc

Voici la fonction pour serveur SQL qui convertit la valeur entière en sa représentation hexadécimale en tant que varchar. Il devrait être facile de s'adapter à d'autres types de bases de données 

Par exemple:

SELECT dbo.ToHex(4095) --> FFF

SQL:

CREATE FUNCTION ToHex(@value int)
RETURNS varchar(50)
AS
BEGIN
    DECLARE @seq char(16)
    DECLARE @result varchar(50)
    DECLARE @digit char(1)
    SET @seq = '0123456789ABCDEF'

    SET @result = SUBSTRING(@seq, (@value%16)+1, 1)

    WHILE @value > 0
    BEGIN
        SET @digit = SUBSTRING(@seq, ((@value/16)%16)+1, 1)

        SET @value = @value/16
        IF @value <> 0 SET @result = @digit + @result
    END 

    RETURN @result
END
GO
5
Maksym Kozlenko

Le format hexadécimal traditionnel de 4 bits est plutôt direct . Chaîne hexadécimale en entier (La valeur supposée est stockée dans un champ appelé FHexString): 

CONVERT(BIGINT,CONVERT(varbinary(4),
                (SELECT master.dbo.fn_cdc_hexstrtobin(

                    LEFT(FMEID_ESN,8)                       
                ))
                ))

Entier en chaîne hexadécimale (la valeur supposée est stockée dans un champ appelé FInteger):

(SELECT master.dbo.fn_varbintohexstr(CONVERT(varbinary,CONVERT(int,
                    FInteger
                ))))

Il est important de noter que lorsque vous commencez à utiliser des tailles de bits qui entraînent le partage de registre, en particulier sur une machine intel, vos valeurs supérieure et inférieure et inférieure et les droits dans les registres seront permutés en raison de la nature peu évolutive d'Intel. Par exemple, lorsque vous utilisez varbinary (3), nous parlons d'un hexagone à 6 caractères. Dans ce cas, vos bits sont appariés comme les index suivants de droite à gauche "54,32,10". Dans un système intel, vous vous attendez à "76,54,32,10". Puisque vous n’utilisez que 6 des 8, vous devez vous rappeler de faire les échanges vous-même. "76,54" sera qualifié de gauche et "32,10" de droit. La virgule sépare votre haut et votre bas. Intel échange les hauts et les bas, puis la gauche et les droits. Donc pour faire une conversion ... soupir, vous devez les échanger vous-même par exemple, ce qui suit convertit les 6 premiers d'un hexagone de 8 caractères:

(SELECT master.dbo.fn_replvarbintoint(
                CONVERT(varbinary(3),(SELECT master.dbo.fn_cdc_hexstrtobin(
                    --intel processors, registers are switched, so reverse them 


                    ----second half
                    RIGHT(FHex8,2)+ --0,1 (0 indexed)
                    LEFT(RIGHT(FHex8,4),2)+ -- 2,3 (oindex)
                    --first half
                    LEFT(RIGHT(FHex8,6),2) --4,5

                )))
                ))

C'est un peu compliqué, alors j'essayais de garder mes conversions en hexadécimal de 8 caractères (varbinary (4)). 

En résumé, cela devrait répondre à votre question. Globalement. 

4
Neel Edwards

Utilisez master.dbo.fnbintohexstr(16777215) pour convertir en une représentation varchar.

2
Ed
Declare @Dato xml
Set @Dato = Convert(xml, '<dato>FF</dato>')
Select Cast( rw.value( 'xs:hexBinary( text()[1])' , 'varbinary(max)' ) as int ) From @Dato.nodes('dato') as T(rw)
2
Donaciano

La réponse de Maksym Kozlenko est Nice et peut être légèrement modifiée pour gérer le codage d’une valeur numérique dans n’importe quel format de code. Par exemple:

CREATE FUNCTION [dbo].[IntToAlpha](@Value int)
RETURNS varchar(30)
AS
BEGIN
    DECLARE @CodeChars varchar(100) 
    SET @CodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    DECLARE @CodeLength int = 26
    DECLARE @Result varchar(30) = ''
    DECLARE @Digit char(1)

    SET @Result = SUBSTRING(@CodeChars, (@Value % @CodeLength) + 1, 1)
    WHILE @Value > 0
    BEGIN
        SET @Digit = SUBSTRING(@CodeChars, ((@Value / @CodeLength) % @CodeLength) + 1, 1)
        SET @Value = @Value / @CodeLength
        IF @Value <> 0 SET @Result = @Digit + @Result
    END 

    RETURN @Result
END

Ainsi, un grand nombre comme 150 millions ne devient que 6 caractères (150 000 000 = "MQGJMU")

Vous pouvez également utiliser différents caractères dans différentes séquences en tant que périphérique de cryptage. Vous pouvez également transmettre les caractères de code et la longueur des caractères et les utiliser comme méthode de salage pour le cryptage.

Et l'inverse:

CREATE FUNCTION [dbo].[AlphaToInt](@Value varchar(7))
RETURNS int
AS
BEGIN
    DECLARE @CodeChars varchar(100) 
    SET @CodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    DECLARE @CodeLength int = 26
    DECLARE @Digit char(1)
    DECLARE @Result int = 0
    DECLARE @DigitValue int
    DECLARE @Index int = 0
    DECLARE @Reverse varchar(7)
    SET @Reverse = REVERSE(@Value)

    WHILE @Index < LEN(@Value)
    BEGIN
        SET @Digit = SUBSTRING(@Reverse, @Index + 1, 1)
        SET @DigitValue = (CHARINDEX(@Digit, @CodeChars) - 1) * POWER(@CodeLength, @Index)
        SET @Result = @Result + @DigitValue
        SET @Index = @Index + 1
    END 
    RETURN @Result
2
Jason Gilley

Donné:

declare @hexStr varchar(16), @intVal int

IntToHexStr:

select @hexStr = convert(varbinary, @intVal, 1)

HexStrToInt:

declare
    @query varchar(100),
    @parameters varchar(50)

select
    @query = 'select @result = convert(int,' + @hb + ')',
    @parameters = '@result int output'

exec master.dbo.Sp_executesql @query, @parameters, @intVal output
1
Bob Platt

Maksym Kozlenko a une solution intéressante, et d’autres se rapprochent de libérant tout son potentiel mais manquent alors complètement de réaliser que vous pouvez définir n’importe quelle séquence de caractères et utilisez it la base . C'est pourquoi j'aime bien cette version légèrement modifiée de sa solution, car elle peut fonctionner pour la base 16, ou la base 17, etc.

Par exemple, si vous vouliez des lettres et des chiffres, mais n'aimez pas que je ressemble à un 1 et à un O à un 0. Vous pouvez définir n'importe quelle séquence de cette façon. Vous trouverez ci-dessous une forme de "base 36" qui ignore les I et O pour créer une "base modifiée 34". Décommentez la ligne hexagonale à la place pour s'exécuter en tant qu'hex.

declare @value int = 1234567890

DECLARE @seq varchar(100) = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ' -- modified base 34
--DECLARE @seq varchar(100) = '0123456789ABCDEF' -- hex
DECLARE @result varchar(50)
DECLARE @digit char(1)
DECLARE @baseSize int = len(@seq)
DECLARE @workingValue int = @value

SET @result = SUBSTRING(@seq, (@workingValue%@baseSize)+1, 1)

WHILE @workingValue > 0
BEGIN
    SET @digit = SUBSTRING(@seq, ((@workingValue/@baseSize)%@baseSize)+1, 1)

    SET @workingValue = @workingValue/@baseSize
    IF @workingValue <> 0 SET @result = @digit + @result
END 

select @value as Value, @baseSize as BaseSize, @result as Result

Value, BaseSize, Result

1234567890, 34, T5URAA

J'ai également transféré la valeur sur une valeur de travail, puis je travaille à partir de la copie de valeur de travail, en tant que préférence personnelle.

Vous trouverez ci-dessous un complément pour l'inversion de la transformation , pour toute séquence, la base étant définie comme étant la longueur de la séquence.

declare @value varchar(50) = 'T5URAA'

DECLARE @seq varchar(100) = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ' -- modified base 34
--DECLARE @seq varchar(100) = '0123456789ABCDEF' -- hex
DECLARE @result int = 0
DECLARE @digit char(1)
DECLARE @baseSize int = len(@seq)
DECLARE @workingValue varchar(50) = @value

DECLARE @PositionMultiplier int = 1
DECLARE @digitPositionInSequence int = 0

WHILE len(@workingValue) > 0
BEGIN
    SET @digit = right(@workingValue,1)
    SET @digitPositionInSequence = CHARINDEX(@digit,@seq)
    SET @result = @result + ( (@digitPositionInSequence -1) * @PositionMultiplier)

    --select @digit, @digitPositionInSequence, @PositionMultiplier, @result

    SET @workingValue = left(@workingValue,len(@workingValue)-1)
    SET @PositionMultiplier = @PositionMultiplier * @baseSize
END 

select @value as Value, @baseSize as BaseSize, @result as Result
0
Greg
IIF(Fields!HIGHLIGHT_COLOUR.Value="","#FFFFFF","#" & hex(Fields!HIGHLIGHT_COLOUR.Value) & StrDup(6-LEN(hex(Fields!HIGHLIGHT_COLOUR.Value)),"0"))

Travaille pour moi comme une expression dans la couleur de police

0
Julian

Pour convertir des chaînes Hex en INT, je l’avais utilisé par le passé. Il peut être modifié pour convertir n'importe quelle base en INT (octal, binaire, peu importe)

Declare @Str varchar(200)
Set @str = 'F000BE1A'

Declare @ndx int
Set @ndx = Len(@str)
Declare @RunningTotal  BigInt
Set @RunningTotal = 0

While @ndx > 0
Begin
    Declare @Exponent BigInt
    Set @Exponent = Len(@Str) - @ndx

    Set @RunningTotal = @RunningTotal + 

    Power(16 * 1.0, @Exponent) *
    Case Substring(@str, @ndx, 1)
        When '0' then 0
        When '1' then 1
        When '2' then 2 
        When '3' then 3
        When '4' then 4
        When '5' then 5
        When '6' then 6
        When '7' then 7
        When '8' then 8
        When '9' then 9
        When 'A' then 10
        When 'B' then 11
        When 'C' then 12
        When 'D' then 13
        When 'E' then 14
        When 'F' then 15
    End
    Set @ndx = @ndx - 1
End

Print @RunningTotal
0
j_s_kelley

Voici deux fonctions: dbo.HexToInt et dbo.IntToHex, je les utilise pour cette conversion:

if OBJECT_ID('dbo.HexToInt') is not null
    drop function dbo.HexToInt
GO
create function dbo.HexToInt (@chars varchar(max))
returns int
begin
    declare @char varchar(1), @len int, @i int, @r int, @tmp int, @pow int
    set @chars = RTRIM(LTRIM(@chars))
    set @len = LEN(@chars)
    set @i = 1
    set @r = 0
    while @i <= @len
    begin
        set @pow = @len - @i
        set @char = SUBSTRING(@chars, @i, 1)
        if @char = '0'
            set @tmp = 0
        else if @char = '1'
            set @tmp = 1
        else if @char = '2'
            set @tmp = 2
        else if @char = '3'
            set @tmp = 3
        else if @char = '4'
            set @tmp = 4
        else if @char = '5'
            set @tmp = 5
        else if @char = '6'
            set @tmp = 6
        else if @char = '7'
            set @tmp = 7
        else if @char = '8'
            set @tmp = 8
        else if @char = '9'
            set @tmp = 9
        else if @char = 'A'
            set @tmp = 10
        else if @char = 'B'
            set @tmp = 11
        else if @char = 'C'
            set @tmp = 12
        else if @char = 'D'
            set @tmp = 13
        else if @char = 'E'
            set @tmp = 14
        else if @char = 'F'
            set @tmp = 15
        set @r = @r + @tmp * POWER(16,@pow)
        set @i = @i + 1     
    end
    return @r
end

Et le second:

if OBJECT_ID('dbo.IntToHex') is not null
    drop function dbo.IntToHex
GO
create function dbo.IntToHex (@val int)
returns varchar(max)
begin
    declare @r varchar(max), @tmp int, @v1 int, @v2 int, @char varchar(1)
    set @tmp = @val
    set @r = ''
    while 1=1
    begin
        set @v1 = @tmp / 16
        set @v2 = @tmp % 16
        if @v2 = 0
            set @char = '0'
        else if @v2 = 1
            set @char = '1'
        else if @v2 = 2
            set @char = '2'
        else if @v2 = 3
            set @char = '3'
        else if @v2 = 4
            set @char = '4'
        else if @v2 = 5
            set @char = '5'
        else if @v2 = 6
            set @char = '6'
        else if @v2 = 7
            set @char = '7'
        else if @v2 = 8
            set @char = '8'
        else if @v2 = 9
            set @char = '9'
        else if @v2 = 10
            set @char = 'A'
        else if @v2 = 11
            set @char = 'B'
        else if @v2 = 12
            set @char = 'C'
        else if @v2 = 13
            set @char = 'D'
        else if @v2 = 14
            set @char = 'E'
        else if @v2 = 15
            set @char = 'F'
        set @tmp = @v1 
        set @r = @char + @r
        if @tmp = 0
            break
    end
    return @r
end
0
byte