Converter inteiro para hex e hex para inteiro
-
22-08-2019 - |
Pergunta
Então eu tenho esse trabalho consulta (onde signal_data
é uma coluna) em Sybase, mas ele não funciona no Microsoft SQL Server:
HEXTOINT(SUBSTRING((INTTOHEX(signal_data)),5,2)) as Signal
Eu também tê-lo em Excel (onde A1
contém o valor):
=HEX2DEC(LEFT(DEC2HEX(A1),LEN(DEC2HEX(A1))-2))
Alguém sabe como eu iria fazer isso no SQL Server?
Solução
Convert INT para hex:
SELECT CONVERT(VARBINARY(8), 16777215)
Convert hex para INT:
SELECT CONVERT(INT, 0xFFFFFF)
Atualização 2015/03/16
O exemplo acima tem a limitação de que só funciona quando o valor hexadecimal é dada como um número inteiro literal. Para completar, se o valor a ser convertido é uma string hexadecimal (como o encontrado em uma coluna varchar) use:
-- 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))
Nota: A cadeia deve conter um número par de dígitos hexadecimais. Um número ímpar de dígitos irá produzir um erro.
Mais detalhes podem ser encontrados na secção "Estilos binários" do CAST e CONVERT (Transact-SQL) . Acredito SQL Server 2008 ou posterior é necessário.
Outras dicas
Na verdade, o master.dbo.fn_varbintohexstr built-in função é chamada.
Assim, por exemplo:
SELECT 100, master.dbo.fn_varbintohexstr(100)
Dá-lhe
100 0x00000064
equivalentes SQL Server para DEC2HEX baseado em texto do Excel, funções HEX2DEC:
--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
Converter int para hex:
SELECT FORMAT(512+255,'X')
É possível usando o formato função disponível em SQL Server 2012 e acima
select FORMAT(10,'x2')
Resultados em:
0a
O bit hex traditonal 4 é bastante direta. Hex String para Integer (valor Assumindo que é armazenado no campo chamado FHexString):
CONVERT(BIGINT,CONVERT(varbinary(4),
(SELECT master.dbo.fn_cdc_hexstrtobin(
LEFT(FMEID_ESN,8)
))
))
Integer para Hex String (valor Assumindo que é armazenado no campo chamado FInteger):
(SELECT master.dbo.fn_varbintohexstr(CONVERT(varbinary,CONVERT(int,
FInteger
))))
importante notar é que quando você começar a usar pouco tamanhos que partilha causa registo, especialmente em uma máquina Intel, a sua alta e baixa e esquerda e Direitos dos registos será trocado devido à natureza pouco endian da Intel. Por exemplo, ao usar um varbinary (3), estamos falando de um Hex 6 personagem. Neste caso, os bits são emparelhados como os seguintes índices da direita para a esquerda "54,32,10". Em um sistema Intel, você pode esperar "76,54,32,10". Desde que você está usando apenas 6 dos 8, você precisa se lembrar de fazer os swaps si mesmo. "76,54" será considerado como a sua esquerda e "32,10" será considerado como sua direita. A vírgula separa a sua alta e baixa. Intel troca a altos e baixos, em seguida, à esquerda e direitos. Então, para fazer uma conversão ... suspiro, você tem que trocá-los-se, por exemplo, os seguintes converte a primeira 6 de um hex de 8 caracteres:
(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
)))
))
É um pouco complicado, então eu tento manter meus conversões a 8 personagem de hex (varbinary (4)).
Em resumo, este deve responder a sua pergunta. De forma abrangente.
Aqui é a função de servidor SQL que converte inteiros valor em sua representação hexadecimal como um varchar. Deve ser fácil de se adaptar a outros tipos de banco de dados
Por exemplo:
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
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)
Use master.dbo.fnbintohexstr(16777215)
para converter a uma representação varchar
.
A resposta por Maksym Kozlenko é agradável e pode ser ligeiramente modificada para lidar com codificação de um valor numérico para qualquer formato de código. Por exemplo:
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
Assim, um grande número como 150 milhões, torna-se apenas 6 caracteres (150.000.000 = "MQGJMU")
Você também pode usar diferentes personagens em diferentes sequências como um dispositivo de criptografar. Ou passar nos personagens de código e comprimento de caracteres e usar como um método de salga para criptografar.
E o inverso:
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
Dada:
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
IIF(Fields!HIGHLIGHT_COLOUR.Value="","#FFFFFF","#" & hex(Fields!HIGHLIGHT_COLOUR.Value) & StrDup(6-LEN(hex(Fields!HIGHLIGHT_COLOUR.Value)),"0"))
Está trabalhando para mim como uma expressão em font color
Para converter cordas Hex para INT, eu usei isso no passado. Ele pode ser modificado para converter qualquer base para INT na verdade (Octal, Binário, qualquer que seja)
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
A seguir estão duas funções: dbo.HexToInt e dbo.IntToHex, eu usá-los para tal conversão:
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
E a segunda:
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
Maksym Kozlenko tem uma boa solução, e outros vêm perto de desbloquear o seu potencial completo , mas, em seguida, perder completamente a conta de que você pode definir qualquer sequência de caracteres, e < strong> uso a sua comprimento que a base de dados . Qual é porque eu como esta versão ligeiramente modificada de sua solução, porque ele pode trabalhar para base 16, ou base 17, e etc.
Por exemplo, se você queria letras e números, mas não como eu é para olhar como 1 os o para olhar como 0 do. Você pode definir qualquer sequência desta forma. Abaixo encontra-se uma forma de uma "base 36", que ignora o I e O para criar uma "base modificada 34". Un-comentário da linha hex em vez de executar como 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
Valor, BaseSize, Resultado
1234567890, 34, T5URAA
Eu também mudou valor ao longo de um valor de trabalho, e depois trabalhar a partir da cópia valor de trabalho, como uma preferência pessoal.
Abaixo é adicional para
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