Konvertieren Sie Integer in Hex und Hex in Integer


78

Ich habe diese Abfrage signal_datain Sybase (wo ist eine Spalte), aber in Microsoft SQL Server funktioniert sie nicht:

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

Ich habe es auch in Excel (wo A1den Wert enthält):

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

Weiß jemand, wie ich das in SQL Server machen würde?

Antworten:


119

Konvertiere INT in hex:

SELECT CONVERT(VARBINARY(8), 16777215)

Hex in INT konvertieren:

SELECT CONVERT(INT, 0xFFFFFF)

Update 2015-03-16

Das obige Beispiel hat die Einschränkung, dass es nur funktioniert, wenn der HEX-Wert als ganzzahliges Literal angegeben wird. Wenn der zu konvertierende Wert eine hexadezimale Zeichenfolge ist (wie in einer Varchar-Spalte), verwenden Sie der Vollständigkeit halber:

-- 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))

Hinweis: Die Zeichenfolge muss eine gerade Anzahl von Hex-Ziffern enthalten. Eine ungerade Anzahl von Ziffern führt zu einem Fehler.

Weitere Details finden Sie im Abschnitt "Binäre Stile" von CAST und CONVERT (Transact-SQL) . Ich glaube, dass SQL Server 2008 oder höher erforderlich ist.


8
Wenn Sie es in VARBINARY konvertieren, erhalten Sie Daten im Hex-Wert. String-Operationen können nicht ausgeführt werden
Pavan

1
@ Bill Karwin, Pavan ist richtig. SQL Server 2008 kann dies über die convertFunktion tun , 2005 und darunter jedoch nicht.
Ben

2
Bei Verwendung von 8-stelligem Hex, z. B. bei ARGB, konvertieren Sie zu BIGINT anstelle von INT. Der Maximalwert für INT beträgt nur 2.147.483.647 oder 7FFFFFFF. Beachten Sie, dass bei Verwendung von INT der Roundtrip zurück zu Hex funktioniert, die Ergebnisse jedoch von Hex2Dec in Excel abweichen.
DenverJT

SELECT CONVERT(INT, CONVERT(varbinary, '01', 2))kehrt zurück 12337 (SQL Server 2005)
Ian Boyd

Die ersten Beispiele werden nicht hexadezimal konvertiert: Sie werden binär konvertiert. (Der Binärwert existiert unabhängig von einer Zahlenbasis: Eine Zahlenbasis ist nur im Kontext einer Zeichenfolgendarstellung sinnvoll.) (Außerdem muss der Parameter kein Literal sein (obwohl er eine Ganzzahl sein muss.)) Sie scheinen möglicherweise in Hexadezimal umzuwandeln, da sie beim Konvertieren von Binär in Zeichenfolge (z. B. zum Anzeigen) standardmäßig in Hexadezimal dargestellt werden. (Dies kann verwendet werden, um in hexadezimal zu konvertieren, wie in @ KipBryans Antwort gezeigt, aber die Antworten von DenNukem und wndproc sind einfacher.)
John B. Lambe


27

SQL Server-Entsprechungen zu den auf Zeichenfolgen basierenden Funktionen DEC2HEX und HEX2DEC von 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


12

Dies ist mit der Funktion FORMAT möglich, die unter SQL Server 2012 und höher verfügbar ist

select FORMAT(10,'x2')

Ergebnisse in:

0a

5

Das traditionelle 4-Bit-Hex ist ziemlich direkt. Hex String to Integer (Angenommen, der Wert wird im Feld FHexString gespeichert):

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

                    LEFT(FMEID_ESN,8)                       
                ))
                ))

Integer to Hex String (Angenommen, der Wert wird im Feld FInteger gespeichert):

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

Es ist wichtig zu beachten, dass, wenn Sie anfangen, Bitgrößen zu verwenden, die eine gemeinsame Nutzung von Registern verursachen, insbesondere auf einem Intel-Computer, Ihre High- und Low- sowie Left- und Rechte in den Registern aufgrund der Little-Endian-Natur von Intel ausgetauscht werden. Wenn Sie beispielsweise eine Varbinary (3) verwenden, sprechen wir von einem 6-stelligen Hex. In diesem Fall werden Ihre Bits als die folgenden Indizes von rechts nach links "54,32,10" gepaart. In einem Intel-System würden Sie "76,54,32,10" erwarten. Da Sie nur 6 der 8 verwenden, müssen Sie daran denken, die Swaps selbst durchzuführen. "76,54" gilt als Ihre Linke und "32,10" als Ihre Rechte. Das Komma trennt Ihr Hoch und Tief. Intel tauscht die Höhen und Tiefen, dann die Linken und die Rechte. Um eine Konvertierung durchzuführen ... seufz, du musst sie zum Beispiel selbst tauschen,

(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

                )))
                ))

Es ist ein bisschen kompliziert, also würde ich versuchen, meine Konvertierungen in Hexs mit 8 Zeichen (varbinary (4)) beizubehalten.

Zusammenfassend sollte dies Ihre Frage beantworten. Umfassend.


5

Hier ist die Funktion für SQL Server, die einen ganzzahligen Wert in seine hexadezimale Darstellung als varchar konvertiert. Die Anpassung an andere Datenbanktypen sollte einfach sein

Zum Beispiel:

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

Es funktioniert! Perfekt! Sie müssen nur "IF @ Wert 0" durch "IF @ Wert <> 0" ersetzen
M07

Ich mag diese Lösung, weil sie leicht in eine noch leistungsstärkere geändert werden kann. Ich lieferte eine solche Beispiellösung für die Verwendung der Länge der Sequenz als Basis.
Greg

3

Verwenden Sie master.dbo.fnbintohexstr(16777215)diese Option , um in eine varcharDarstellung zu konvertieren .


1
select master.sys.fn_varbintohexstr(1)im Jahr 2008
ekkis

2
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

Die Antwort von Maksym Kozlenko ist nett und kann leicht geändert werden, um die Codierung eines numerischen Werts in ein beliebiges Codeformat zu handhaben. Zum Beispiel:

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

Eine große Zahl wie 150 Millionen wird also nur zu 6 Zeichen (150.000.000 = "MQGJMU").

Sie können auch verschiedene Zeichen in verschiedenen Sequenzen als Verschlüsselungsgerät verwenden. Oder geben Sie die Codezeichen und die Länge der Zeichen ein und verwenden Sie sie als Salting-Methode zum Verschlüsseln.

Und umgekehrt:

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

1

Gegeben:

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

Maksym Kozlenko hat eine schöne Lösung, und andere nahe kommen sie das volle Potenzial Entriegeln aber dann verpassen vollständig realisiert , dass Sie eine beliebige Folge von Zeichen definieren, und verwenden sie die Länge wie die Basis . Aus diesem Grund mag ich diese leicht modifizierte Version seiner Lösung, da sie für Base 16 oder Base 17 usw. funktionieren kann.

Was wäre zum Beispiel, wenn Sie Buchstaben und Zahlen wollten, aber nicht mögen, dass ich wie Einsen und Os wie Nullen aussehe? Auf diese Weise können Sie eine beliebige Sequenz definieren. Unten ist eine Form einer "Basis 36", die das I und O überspringt, um eine "modifizierte Basis 34" zu erstellen. Deaktivieren Sie stattdessen die Hex-Linie, um sie als Hex auszuführen.

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

Wert, Basisgröße, Ergebnis

1234567890, 34, T5URAA

Ich habe auch den Wert auf einen Arbeitswert verschoben und dann als persönliche Präferenz von der Arbeitswertkopie aus gearbeitet.

Im Folgenden finden Sie zusätzliche Informationen zum Umkehren der Transformation für eine beliebige Sequenz, wobei die Basis als Länge der Sequenz definiert ist.

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
IIF(Fields!HIGHLIGHT_COLOUR.Value="","#FFFFFF","#" & hex(Fields!HIGHLIGHT_COLOUR.Value) & StrDup(6-LEN(hex(Fields!HIGHLIGHT_COLOUR.Value)),"0"))

Arbeitet für mich als Ausdruck in Schriftfarbe


0

Um Hex-Strings in INT zu konvertieren, habe ich dies in der Vergangenheit verwendet. Es kann so geändert werden, dass jede Basis tatsächlich in INT konvertiert wird (Oktal, Binär, was auch immer).

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

Im Folgenden sind zwei Funktionen aufgeführt: dbo.HexToInt und dbo.IntToHex. Ich verwende sie für eine solche Konvertierung:

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

Und der zweite:

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.