Android Question Convert String.format("%032x", new BigInteger(1, md.digest())) to B4a

somed3v3loper

Well-Known Member
Licensed User
Hello all ,

I am trying to convert the following Java to B4A but have no luck in converting string.format("%032x", new BigInteger(1, md.digest()));

Can you please help ?


B4X:
 MessageDigest md = MessageDigest.getInstance("MD5");
      long timeInSeconds = (System.currentTimeMillis() / 1000);
      String input = apikey + secret + timeInSeconds;
      md.update(input.getBytes());
      String sig = String.format("%032x", new BigInteger(1, md.digest()));

      String url = service + version + method  + "?apikey=" + apikey
         + "&sig=" + sig + otherElementsStr + "hotelIdList=" + hotelId;


B4X:
Sub hashing
    Dim md As MessageDigest
    Dim input As String="my api key"&"secret"&(DateTime.Now/1000)
 

    Dim bint As JavaObject
    bint.InitializeNewInstance("java.math.BigInteger",Array(1,md.GetMessageDigest(input.GetBytes("UTF8"),"MD5")))
    Log(bint)
    FormatString(bint,"%032x")
 

End Sub
Sub FormatString(str As String,strformat As String) As String
'Create a Stringbuilder (it's much faster for appending strings)
    Log("STR: "&str)
    Dim SB As StringBuilder
    SB.Initialize

    'Create the Formatter Object
    Dim Format As JavaObject
    Format.InitializeStatic("java.lang.String")

    'Create an array of arrays that holds our data.
    'We could have been read from a CSV file using StringUtils and converted to an array of arrays using Regex.Split

    'NOTE: the array must be of type Object

    Dim Data(1) As Object
    Data(0) = Array As Object(str)
'    Data(1) = Array As Object("Peter","2","Home","\n")
'    Data(2) = Array As Object("Michael","3","Away","\n")
'    Data(3) = Array As Object("Ann","4","Home","\n")
    Log("0: "&Data(0))
    Dim FormatStr As String = strformat

    For Each Line() As Object In Data
        Log(Line)
        SB.Append(Format.RunMethod("format",Array As Object(FormatStr,Line)))
    Next

    Return SB.ToString


End Sub
I used a snippet from forums but I think I am not implementing it correctly.
Thanks in advance
 

stevel05

Expert
Licensed User
You are passing a javaobject (bint) to the FormatString Sub that requires a String as it's first parameter, have you checked to see that it is converted successfully to a string?
 

somed3v3loper

Well-Known Member
Licensed User
You are passing a javaobject (bint) to the FormatString Sub that requires a String as it's first parameter, have you checked to see that it is converted successfully to a string?
I got this error

B4X:
Caused by: java.util.IllegalFormatConversionException: %x can't format java.lang.String arguments
when using toString method

B4X:
FormatString(bint.RunMethod("toString",Null),"%032x")
 

stevel05

Expert
Licensed User
The two pieces of code use two different methods, the Java code is using String.Format, whereas the B4a code is using Format.Format, I don't now if there are differences.

Do you need to convert to a BigInteger first? Could you not just format the string returned by md.GetMessageDigest ?
 

somed3v3loper

Well-Known Member
Licensed User
The two pieces of code use two different methods, the Java code is using String.Format, whereas the B4a code is using Format.Format, I don't now if there are differences.

Do you need to convert to a BigInteger first? Could you not just format the string returned by md.GetMessageDigest ?
Thank you Stevel for following up.
I wanted to use string.format but couldn't implement it like the Java code I posted at the first post.
 

stevel05

Expert
Licensed User
What does bint.RunMethod("toString",Null) return on it's own?
 

stevel05

Expert
Licensed User
And what is the format of md.GetMessageDigest(input.GetBytes("UTF8")?
 

somed3v3loper

Well-Known Member
Licensed User
What does bint.RunMethod("toString",Null) return on it's own?
A number like this : 80031998492074665507531940202557360092

And what is the format of md.GetMessageDigest(input.GetBytes("UTF8")?
I am not sure I just want to convert this java code


B4X:
      MessageDigest md = MessageDigest.getInstance("MD5");
      long timeInSeconds = (System.currentTimeMillis() / 1000);
      String input = apikey + secret + timeInSeconds;
      md.update(input.getBytes());
      String sig = String.format("%032x", new BigInteger(1, md.digest()));
 

stevel05

Expert
Licensed User
What does the line
Log("STR: "&str)

Display at the beginning of the Sub?
 

somed3v3loper

Well-Known Member
Licensed User
What does the line
Log("STR: "&str)

Display at the beginning of the Sub?
If I am passing bint (the java object ) , it logs like STR: (BigInteger) 325439218251559342963858582458042399582
if I use toString method , it logs just the number like 325439218251559342963858582458042399582
 

somed3v3loper

Well-Known Member
Licensed User
Any help ?

B4X:
    Dim Formatr As JavaObject
    Formatr.InitializeStatic("java.lang.String")
    Formatr.RunMethod("format",Array(bint,"%032x"))
I tried passing bint As JavaObject
bint.InitializeNewInstance("java.math.BigInteger",Array(1,md.GetMessageDigest(input.GetBytes("UTF8"),"MD5")))
and even passing bint.RunMethod("toString",Null)

all would crash with java.lang.RuntimeException: Method: format not matched. error
 

stevel05

Expert
Licensed User
The point I was trying to make was to try it without converting to a big integer, if the string representation gives the same number as the big integer, it may format correctly without converting to a big integer first.
 

somed3v3loper

Well-Known Member
Licensed User
The point I was trying to make was to try it without converting to a big integer, if the string representation gives the same number as the big integer, it may format correctly without converting to a big integer first.
I tried to pass strings and numbers to string.format but in all cases I get Method: format not matched
Can you please check if my method of using string.format is working properly ?
 

stevel05

Expert
Licensed User
This appears to work:

B4X:
    Dim bint As JavaObject
    bint.InitializeNewInstance("java.math.BigInteger",Array("325439218251559342963858582458042399582"))
   
    Dim Format As JavaObject
    Format.InitializeStatic("java.lang.String")
       
    Dim FormatStr As String = "%032x"
    Dim Val(1) As Object
    Val(0) = bint

    Log(Format.RunMethod("format",Array(FormatStr,Val)))
The Value passed must be in an Object Array, the format string is the first parameter to be passed.
 

somed3v3loper

Well-Known Member
Licensed User
This appears to work:

B4X:
    Dim bint As JavaObject
    bint.InitializeNewInstance("java.math.BigInteger",Array("325439218251559342963858582458042399582"))
  
    Dim Format As JavaObject
    Format.InitializeStatic("java.lang.String")
      
    Dim FormatStr As String = "%032x"
    Dim Val(1) As Object
    Val(0) = bint

    Log(Format.RunMethod("format",Array(FormatStr,Val)))
The Value passed must be in an Object Array, the format string is the first parameter to be passed.
Thanks Stevel

I think my problem is because I am passing
B4X:
md.GetMessageDigest(input.GetBytes("UTF8"),"MD5")
to
B4X:
bint.InitializeNewInstance("java.math.BigInteger",Array(HERE))
B4X:
md.GetMessageDigest(input.GetBytes("UTF8"),"MD5")
returns
B4X:
byte()
but as your example above you passed a string .

Now I do not know what to do
 

stevel05

Expert
Licensed User
Try This:

B4X:
Dim B(32) As Byte = Array As Byte(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31)
    Dim bint As JavaObject
    bint.InitializeNewInstance("java.math.BigInteger",Array(1,B))
   
    Dim Format As JavaObject
    Format.InitializeStatic("java.lang.String")
       
    Dim FormatStr As String = "%032x"
    Dim Val(1) As Object
    Val(0) = bint

    Log(Format.RunMethod("format",Array(FormatStr,Val)))
From the original code, the BigInteger is initialized with a byte array instead of a string.
 
Top