0

How to convert a Long/ULong representing an unsigned long to an unsigned hexadecimal string with padding zeros (a 16-digit hexadecimal string)?

I am looking for a simple and neat solution in Kotlin or Java.

Shreck Ye
  • 1,591
  • 2
  • 16
  • 32

2 Answers2

4
val mutableList = listOf(121212L, 121212121212L,-1L)
mutableList.forEach {
    println(it.toULong().toString(16).padStart(16, '0'))
}

it gives

000000000001d97c
0000001c38ce307c
ffffffffffffffff

Edited: Credit to Ilya in the comment for the missing toULong part.

fangzhzh
  • 2,172
  • 21
  • 25
  • This doesn't work for numbers represented by minus longs (greater than or equal to 2^63). For example, for a number stored as -1 I want "ffffffffffffffff", but this solution gives "00000000000000-1". – Shreck Ye May 31 '19 at 08:31
  • 2
    The only missing part here is converting a long value to ULong before invoking toString: `it.toULong().toString(16).padStart(16, '0')` – Ilya Jun 01 '19 at 09:04
  • Although this solution is longer and looks more complicated than the one I found below using `String.format`, it only runs for about 10% of the time it takes to run mine. It's probably because parsing a format string is slow. So this is indeed a better answer. – Shreck Ye Jun 03 '19 at 04:32
2

I have found the solution using x/X in String.format():

fun Long.to16DigitUnsignedLowercaseHexString() =
    "%016x".format(this)

fun Long.to16DigitUnsignedUppercaseHexString() =
    "%016X".format(this)

I have tested that it works for boundary values 0L, 1L, Long.MAX_VALUE, -1L, and Long.MIN_VALUE, so there should be no problems.

A similar question is asked in java - How can I pad an integer with zeros on the left? - Stack Overflow. When looking at this for the first time, I didn't expect it to work because I thought that x/X is for signed hexadecimal formatting. It turned out I was wrong and x/X is exactly for unsigned hexadecimal formatting.

Shreck Ye
  • 1,591
  • 2
  • 16
  • 32