Printing hexadecimal values of a string

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Printing hexadecimal values of a string

Geoffroy Couprie
Hello all,

I get a strange behaviour while trying to print hexadecimal values of a string.

Context: I get a SHA1 hash from a binary stream, store it into a
string, and I want to display that string (using asHex).

Problem: for values inferior to 16, the leading zero is ignored. (15
-> 'F' instead of '0F').

I could modify SmallInteger>>printStringBase: to always include the
leading zero, but I fear I'm going to break a lot of code doing that.
Is there a better way to fix my problem? apart from using directly the
following:
 aStream do:[:val | val printStringBase:16 nDigits:2]

Best regards,

Geoffroy

Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Sven Van Caekenberghe
Hi Geoffroy,

On 19 Dec 2010, at 21:55, Geoffroy Couprie wrote:

> Hello all,
>
> I get a strange behaviour while trying to print hexadecimal values of a string.
>
> Context: I get a SHA1 hash from a binary stream, store it into a
> string, and I want to display that string (using asHex).
>
> Problem: for values inferior to 16, the leading zero is ignored. (15
> -> 'F' instead of '0F').
>
> I could modify SmallInteger>>printStringBase: to always include the
> leading zero, but I fear I'm going to break a lot of code doing that.
> Is there a better way to fix my problem? apart from using directly the
> following:
> aStream do:[:val | val printStringBase:16 nDigits:2]
>
> Best regards,
>
> Geoffroy

Why would you not use the ByteArray>>#hex method ?

#(0 1 2 253 254 255) asByteArray hex

'000102fdfeff'

Sven


Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Max Leske
I know how your feel. My code:

hexHashFrom: aByteString
        "#hex will omit a leading 0. If that's the case insert leading 0."
        ^aByteString asByteArray hex asLowercase forceTo: 40 paddingStartWith: $0

Max


On 19.12.2010, at 22:54, Sven Van Caekenberghe wrote:

> Hi Geoffroy,
>
> On 19 Dec 2010, at 21:55, Geoffroy Couprie wrote:
>
>> Hello all,
>>
>> I get a strange behaviour while trying to print hexadecimal values of a string.
>>
>> Context: I get a SHA1 hash from a binary stream, store it into a
>> string, and I want to display that string (using asHex).
>>
>> Problem: for values inferior to 16, the leading zero is ignored. (15
>> -> 'F' instead of '0F').
>>
>> I could modify SmallInteger>>printStringBase: to always include the
>> leading zero, but I fear I'm going to break a lot of code doing that.
>> Is there a better way to fix my problem? apart from using directly the
>> following:
>> aStream do:[:val | val printStringBase:16 nDigits:2]
>>
>> Best regards,
>>
>> Geoffroy
>
> Why would you not use the ByteArray>>#hex method ?
>
> #(0 1 2 253 254 255) asByteArray hex
>
> '000102fdfeff'
>
> Sven
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Stéphane Ducasse
In reply to this post by Geoffroy Couprie


On Dec 19, 2010, at 9:55 PM, Geoffroy Couprie wrote:

> Hello all,
>
> I get a strange behaviour while trying to print hexadecimal values of a string.
>
> Context: I get a SHA1 hash from a binary stream, store it into a
> string, and I want to display that string (using asHex).
>
> Problem: for values inferior to 16, the leading zero is ignored. (15
> -> 'F' instead of '0F').

indeed printStringHex prints F instead of 0F
15 printStringHex
  'F'
15 hex
        '16rF'

Geoffroy could you add a variant that produces the correct behavior with some tests?

> I could modify SmallInteger>>printStringBase: to always include the
> leading zero, but I fear I'm going to break a lot of code doing that.
> Is there a better way to fix my problem? apart from using directly the
> following:
> aStream do:[:val | val printStringBase:16 nDigits:2]
>
> Best regards,
>
> Geoffroy
>


Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Stéphane Ducasse
In reply to this post by Max Leske
max on which class do you define it?

do you have some tests?

Stef

On Dec 19, 2010, at 11:40 PM, Max Leske wrote:

> I know how your feel. My code:
>
> hexHashFrom: aByteString
> "#hex will omit a leading 0. If that's the case insert leading 0."
> ^aByteString asByteArray hex asLowercase forceTo: 40 paddingStartWith: $0
>
> Max
>
>
> On 19.12.2010, at 22:54, Sven Van Caekenberghe wrote:
>
>> Hi Geoffroy,
>>
>> On 19 Dec 2010, at 21:55, Geoffroy Couprie wrote:
>>
>>> Hello all,
>>>
>>> I get a strange behaviour while trying to print hexadecimal values of a string.
>>>
>>> Context: I get a SHA1 hash from a binary stream, store it into a
>>> string, and I want to display that string (using asHex).
>>>
>>> Problem: for values inferior to 16, the leading zero is ignored. (15
>>> -> 'F' instead of '0F').
>>>
>>> I could modify SmallInteger>>printStringBase: to always include the
>>> leading zero, but I fear I'm going to break a lot of code doing that.
>>> Is there a better way to fix my problem? apart from using directly the
>>> following:
>>> aStream do:[:val | val printStringBase:16 nDigits:2]
>>>
>>> Best regards,
>>>
>>> Geoffroy
>>
>> Why would you not use the ByteArray>>#hex method ?
>>
>> #(0 1 2 253 254 255) asByteArray hex
>>
>> '000102fdfeff'
>>
>> Sven
>>
>>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Levente Uzonyi-2
In reply to this post by Stéphane Ducasse
On Mon, 20 Dec 2010, Stéphane Ducasse wrote:

>
>
> On Dec 19, 2010, at 9:55 PM, Geoffroy Couprie wrote:
>
>> Hello all,
>>
>> I get a strange behaviour while trying to print hexadecimal values of a string.
>>
>> Context: I get a SHA1 hash from a binary stream, store it into a
>> string, and I want to display that string (using asHex).
>>
>> Problem: for values inferior to 16, the leading zero is ignored. (15
>> -> 'F' instead of '0F').
>
> indeed printStringHex prints F instead of 0F
> 15 printStringHex
> 'F'
> 15 hex
> '16rF'
>
> Geoffroy could you add a variant that produces the correct behavior with some tests?
No need to do that. As Sven pointed out, he can simply use ByteArray >>
#hex. Since his stream is already binary, he can also avoid converting his
data to a string.


Levente

>
>> I could modify SmallInteger>>printStringBase: to always include the
>> leading zero, but I fear I'm going to break a lot of code doing that.
>> Is there a better way to fix my problem? apart from using directly the
>> following:
>> aStream do:[:val | val printStringBase:16 nDigits:2]
>>
>> Best regards,
>>
>> Geoffroy
>>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Geoffroy Couprie
Hello,

2010/12/20 Levente Uzonyi <[hidden email]>:

> On Mon, 20 Dec 2010, Stéphane Ducasse wrote:
>
>>
>>
>> On Dec 19, 2010, at 9:55 PM, Geoffroy Couprie wrote:
>>
>>> Hello all,
>>>
>>> I get a strange behaviour while trying to print hexadecimal values of a
>>> string.
>>>
>>> Context: I get a SHA1 hash from a binary stream, store it into a
>>> string, and I want to display that string (using asHex).
>>>
>>> Problem: for values inferior to 16, the leading zero is ignored. (15
>>> -> 'F' instead of '0F').
>>
>> indeed printStringHex prints F instead of 0F
>> 15 printStringHex
>>        'F'
>> 15 hex
>>        '16rF'
>>
>> Geoffroy could you add a variant that produces the correct behavior with
>> some tests?
>
> No need to do that. As Sven pointed out, he can simply use ByteArray >>
> #hex. Since his stream is already binary, he can also avoid converting his
> data to a string.
>

More context: I am using a ZLibReadStream and its upTo: method, which
gives me a ByteString, not a ByteArray. I guess I could convert it to
a ByteArray.

But I still think there's a bug here: printing the hex value of a
Character should add the leading zero, because they're represented by
a full byte.

So, I propose this change:

Character>>hex
   ^value printStringBase: 16 nDigits: 2

Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Levente Uzonyi-2
On Mon, 20 Dec 2010, Geoffroy Couprie wrote:

> Hello,
>
> 2010/12/20 Levente Uzonyi <[hidden email]>:
>> On Mon, 20 Dec 2010, Stéphane Ducasse wrote:
>>
>>>
>>>
>>> On Dec 19, 2010, at 9:55 PM, Geoffroy Couprie wrote:
>>>
>>>> Hello all,
>>>>
>>>> I get a strange behaviour while trying to print hexadecimal values of a
>>>> string.
>>>>
>>>> Context: I get a SHA1 hash from a binary stream, store it into a
>>>> string, and I want to display that string (using asHex).
>>>>
>>>> Problem: for values inferior to 16, the leading zero is ignored. (15
>>>> -> 'F' instead of '0F').
>>>
>>> indeed printStringHex prints F instead of 0F
>>> 15 printStringHex
>>>        'F'
>>> 15 hex
>>>        '16rF'
>>>
>>> Geoffroy could you add a variant that produces the correct behavior with
>>> some tests?
>>
>> No need to do that. As Sven pointed out, he can simply use ByteArray >>
>> #hex. Since his stream is already binary, he can also avoid converting his
>> data to a string.
>>
>
> More context: I am using a ZLibReadStream and its upTo: method, which
> gives me a ByteString, not a ByteArray. I guess I could convert it to
> a ByteArray.
>
> But I still think there's a bug here: printing the hex value of a
> Character should add the leading zero, because they're represented by
> a full byte.
>
> So, I propose this change:
>
> Character>>hex
>   ^value printStringBase: 16 nDigits: 2
>
>
What about this?

(Character value: 12345) hex


Levente
Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Geoffroy Couprie
2010/12/20 Levente Uzonyi <[hidden email]>:

> On Mon, 20 Dec 2010, Geoffroy Couprie wrote:
>
>> Hello,
>>
>> 2010/12/20 Levente Uzonyi <[hidden email]>:
>>>
>>> On Mon, 20 Dec 2010, Stéphane Ducasse wrote:
>>>
>>>>
>>>>
>>>> On Dec 19, 2010, at 9:55 PM, Geoffroy Couprie wrote:
>>>>
>>>>> Hello all,
>>>>>
>>>>> I get a strange behaviour while trying to print hexadecimal values of a
>>>>> string.
>>>>>
>>>>> Context: I get a SHA1 hash from a binary stream, store it into a
>>>>> string, and I want to display that string (using asHex).
>>>>>
>>>>> Problem: for values inferior to 16, the leading zero is ignored. (15
>>>>> -> 'F' instead of '0F').
>>>>
>>>> indeed printStringHex prints F instead of 0F
>>>> 15 printStringHex
>>>>        'F'
>>>> 15 hex
>>>>        '16rF'
>>>>
>>>> Geoffroy could you add a variant that produces the correct behavior with
>>>> some tests?
>>>
>>> No need to do that. As Sven pointed out, he can simply use ByteArray >>
>>> #hex. Since his stream is already binary, he can also avoid converting
>>> his
>>> data to a string.
>>>
>>
>> More context: I am using a ZLibReadStream and its upTo: method, which
>> gives me a ByteString, not a ByteArray. I guess I could convert it to
>> a ByteArray.
>>
>> But I still think there's a bug here: printing the hex value of a
>> Character should add the leading zero, because they're represented by
>> a full byte.
>>
>> So, I propose this change:
>>
>> Character>>hex
>>  ^value printStringBase: 16 nDigits: 2
>>
>>
>
> What about this?
>
> (Character value: 12345) hex
>

Huh, I forgot multibyte characters... Then would this be sufficient?

Character>>hex
    value >255
        ifTrue: [^value hex]
        ifFalse: [^value printStringBase: 16 nDigits: 2]

Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Stéphane Ducasse
>
> Huh, I forgot multibyte characters... Then would this be sufficient?
>
> Character>>hex
>    value >255
>        ifTrue: [^value hex]
>        ifFalse: [^value printStringBase: 16 nDigits: 2]
>

geoffroy

we cannot really change hex because hex returns
        16rXXX

and the other classes are consistent with that.

(Character value: 12345) hex
        '16r3039'


Integer>>hex
        "Print the receiver as hex, prefixed with 16r.  DO NOT CHANGE THIS!  The Cog VMMaker depends on this.
         Consider using any of
                printStringHex
                printStringBase: 16
                printStringBase: 16 length: 8 padded: true
                storeStringHex
                storeStringBase: 16
                storeStringBase: 16 length: 11 padded: true"
        ^self storeStringBase: 16

Now what we could have is another method named:
        xxPrintStringHex
        for example (first name that came to my mind)
        paddedPrintStringHex

1566 printStringHex '61E'

15 printStringHex
 'F'

1566 paddedPrintStringHex '61E'

15 paddedPrintStringHex
 '0F'

Or something like that.

Stef
Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Geoffroy Couprie
On Mon, Dec 20, 2010 at 1:31 PM, Stéphane Ducasse
<[hidden email]> wrote:

>>
>> Huh, I forgot multibyte characters... Then would this be sufficient?
>>
>> Character>>hex
>>    value >255
>>        ifTrue: [^value hex]
>>        ifFalse: [^value printStringBase: 16 nDigits: 2]
>>
>
> geoffroy
>
> we cannot really change hex because hex returns
>        16rXXX
>
> and the other classes are consistent with that.
>
> (Character value: 12345) hex
>        '16r3039'
>
>
> Integer>>hex
>        "Print the receiver as hex, prefixed with 16r.  DO NOT CHANGE THIS!  The Cog VMMaker depends on this.
>         Consider using any of
>                printStringHex
>                printStringBase: 16
>                printStringBase: 16 length: 8 padded: true
>                storeStringHex
>                storeStringBase: 16
>                storeStringBase: 16 length: 11 padded: true"
>        ^self storeStringBase: 16
>
> Now what we could have is another method named:
>        xxPrintStringHex
>        for example (first name that came to my mind)
>        paddedPrintStringHex
>
> 1566 printStringHex '61E'
>
> 15 printStringHex
>  'F'
>
> 1566 paddedPrintStringHex '61E'
>
> 15 paddedPrintStringHex
>  '0F'
>
> Or something like that.
>

I was using Pharo 1.1, where PrintStringHex is not implemented. In the
patch for issue 3466, I modified printStringHex, but a new function
including padding might be a better idea. Until Pharo 1.2 is
published, I'll keep my custom code to display hexadecimal strings.

Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

Max Leske
In reply to this post by Stéphane Ducasse
Hi Stef

Sorry, I should have been more specific. This is a method I use in my own application. I'm not sure if I did test the method but I could have a look if you like.

Max


On 20.12.2010, at 09:11, Stéphane Ducasse wrote:

> max on which class do you define it?
>
> do you have some tests?
>
> Stef
>
> On Dec 19, 2010, at 11:40 PM, Max Leske wrote:
>
>> I know how your feel. My code:
>>
>> hexHashFrom: aByteString
>> "#hex will omit a leading 0. If that's the case insert leading 0."
>> ^aByteString asByteArray hex asLowercase forceTo: 40 paddingStartWith: $0
>>
>> Max
>>
>>
>> On 19.12.2010, at 22:54, Sven Van Caekenberghe wrote:
>>
>>> Hi Geoffroy,
>>>
>>> On 19 Dec 2010, at 21:55, Geoffroy Couprie wrote:
>>>
>>>> Hello all,
>>>>
>>>> I get a strange behaviour while trying to print hexadecimal values of a string.
>>>>
>>>> Context: I get a SHA1 hash from a binary stream, store it into a
>>>> string, and I want to display that string (using asHex).
>>>>
>>>> Problem: for values inferior to 16, the leading zero is ignored. (15
>>>> -> 'F' instead of '0F').
>>>>
>>>> I could modify SmallInteger>>printStringBase: to always include the
>>>> leading zero, but I fear I'm going to break a lot of code doing that.
>>>> Is there a better way to fix my problem? apart from using directly the
>>>> following:
>>>> aStream do:[:val | val printStringBase:16 nDigits:2]
>>>>
>>>> Best regards,
>>>>
>>>> Geoffroy
>>>
>>> Why would you not use the ByteArray>>#hex method ?
>>>
>>> #(0 1 2 253 254 255) asByteArray hex
>>>
>>> '000102fdfeff'
>>>
>>> Sven
>>>
>>>
>>
>>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Printing hexadecimal values of a string

csrabak
In reply to this post by Stéphane Ducasse
I don't want to start a philosophical discussion, but I'm puzzled: What constitutes "correct" behaviour in this case?

Are you saying that 'correct' would be something like:

1 printStringHex
 '0F'

and

1 hex
 '16r01'
 
??



Em 20/12/2010 06:10, Stéphane Ducasse < [hidden email] > escreveu:


On Dec 19, 2010, at 9:55 PM, Geoffroy Couprie wrote:

> Hello all,
>
> I get a strange behaviour while trying to print hexadecimal values of a string.
>
> Context: I get a SHA1 hash from a binary stream, store it into a
> string, and I want to display that string (using asHex).
>
> Problem: for values inferior to 16, the leading zero is ignored. (15
> -> 'F' instead of '0F').

indeed printStringHex prints F instead of 0F
15 printStringHex
 'F'
15 hex
 '16rF'

Geoffroy could you add a variant that produces the correct behavior with some tests?

> I could modify SmallInteger>>printStringBase: to always include the
> leading zero, but I fear I'm going to break a lot of code doing that.
> Is there a better way to fix my problem? apart from using directly the
> following:
> aStream do:[:val | val printStringBase:16 nDigits:2]
>
> Best regards,
>
> Geoffroy
>