Question

I have an issue converting the following hex string to ascii in tsql:

'd520088000000000000000004000000200000000000003770001c7cc5353482d322e302d4f70656e5353485f352e3570312044656269616e2d347562756e7475340d0a0000034c0614403d6544c243e7535320dc7ab5c3c8de0000007e6469666669652d68656c6c6d616e2d67726f75702d65786368616e67652d7368613235362c6469666669652d68656c6c6d616e2d67726f75702d65786368616e67652d736861312c6469666669652d68656c6c6d616e2d67726f757031342d736861312c6469666669652d68656c6c6d616e2d67726f7570312d73686131000000497373682d7273612d636572742d763030406f70656e7373682e636f6d2c7373682d6473732d636572742d763030406f70656e7373682e636f6d2c7373682d7273612c7373682d6473730000009d6165733132382d6374722c6165733139322d6374722c6165733235362d6374722c617263666f75723235362c617263666f75723132382c6165733132382d6362632c336465732d6362632c626c6f77666973682d6362632c636173743132382d6362632c6165733139322d6362632c6165733235362d6362632c617263666f75722c72696a6e6461656c2d636263406c797361746f722e6c69752e73650000009d6165733132382d6374722c6165733139322d6374722c6165733235362d6374722c617263666f75723235362c617263666f75723132382c6165733132382d6362632c336465732d6362632c626c6f77666973682d6362632c636173743132382d6362632c6165733139322d6362632c6165733235362d6362632c617263666f75722c72696a6e6461656c2d636263406c797361746f722e6c69752e736500000069686d61632d6d64352c686d61632d736861312c756d61632d3634406f70656e7373682e636f6d2c686d61632d726970656d643136302c686d61632d726970656d64313630406f70656e7373682e636f6d2c686d61632d736861312d39362c686d61632d6d64352d393600000069686d61632d6d64352c686d61632d736861312c756d61632d3634406f70656e7373682e636f6d2c686d61632d726970656d643136302c686d61632d726970656d64313630406f70656e7373682e636f6d2c686d61632d736861312d39362c686d61632d6d64352d39360000001a6e6f6e652c7a6c6962406f70656e7373682e636f6d2c7a6c69620000001a6e6f6e652c7a6c6962406f70656e7373682e636f6d2c7a6c69620000000000000000000000000000000000000000'

It should convert to

'? ??????????@??????????w????SSH-2.0-OpenSSH_5.5p1 Debian-4ubuntu4?????L??@=eD?C?SS ?z???????~diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1???Issh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ssh-rsa,ssh-dss????aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se????aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se???ihmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96???ihmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96????none,zlib@openssh.com,zlib????none,zlib@openssh.com,zlib????????????????????'

Any ideas? I tried using cast and convert but no success. Any help is much appreciated.

I am using the below function no outside code - tables are populated by an external application

*

declare @hexstring VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
begin
 declare @char1 char(1), @char2 char(1), @strlen int, @currpos int, @result varchar(8000)
 set @strlen=len(@hexstring)
 set @currpos=1
 set @result=''
 while @currpos<@strlen
  begin
   set @char1=substring(@hexstring,@currpos,1)
   set @char2=substring(@hexstring,@currpos+1,1)
   if (@char1 between '0' and '9' or @char1 between 'A' and 'F')
    and (@char2 between '0' and '9' or @char2 between 'A' and 'F')
    set @result=@result+
     char((ascii(@char1)-case when @char1 between '0' and '9' then 48 else 55 end)*16+
     ascii(@char2)-case when @char2 between '0' and '9' then 48 else 55 end)
   set @currpos = @currpos+2
  end
 return @result
end
GO

*

Was it helpful?

Solution

Here is a SQL function that will convert a hex string:

BEGIN

  DECLARE @hexstring AS VARCHAR(8000)
  SET @hexstring = '4368726973204Ce4747461' 

  DECLARE @strlen AS INT;
  SET @strlen = Len(@hexstring)

  DECLARE @currpos AS INT
  SET @currpos = 1

  DECLARE @hexpos AS VARCHAR(16)
  SET @hexpos = '0123456789abcdef'

  DECLARE @result AS VARCHAR(8000)
  SET @result = ''
  DECLARE @ch AS INT

  WHILE @currpos < @strlen
  BEGIN
    SET @ch = CONVERT( INT, 16 * (CHARINDEX( SUBSTRING( @hexstring, @currpos, 1), @hexpos, 1) - 1) 
              + (CHARINDEX(SUBSTRING(@hexstring, @currpos+1, 1), @hexpos, 1) - 1))

    SET @result = @result + CASE WHEN @ch >= 32 AND @ch < 128 THEN CHAR(@ch) ELSE '?' END

    SET @currpos = @currpos + 2                      
  END

  SELECT @result  
END  

I added a short hex string to show the function works.

Your hex string didn't convert so well. It may be because of the nulls in it, so I added the @char >= 32 part to strip out control codes (only convert printable ASCII characters, otherwise insert a ?) and you get a string that looks like the one you are after.

OTHER TIPS

The conversion can be done with a single statement. Since you were using a function I provided my answer as such. Note that this solution requires that the input @hexstring is not prefixed with 0x.

CREATE FUNCTION [dbo].[HexToAscii] 
(
    @hexstring VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
    RETURN CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), @hexstring, 2))
END
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top