Transforming a Java UUID object to a .NET GUID string - java

In a Java method that receives a java.util.UUID Object, I would like to display this object as a string in the .NET/C# format (CSUUID).
Currently I am only able to display it in the Java format (JUUID) :
static String GetStringFromUuid (java.util.UUID myUuid){
return myUuid.toString();
}
Current output: "46c7220b-1f25-0118-f013-03bd2c22d6b8"
Desired output: "1f250118-220b-46c7-b8d6-222cbd0313f0"
Context:
The UUID is stored in MongoDB and is retrieved with the Java ETL program Talend (tMongoDBInput component).
In the Java program, the method already receives the UUID as a java.util.UUID Object (I do not have directly access to the BinData in the program).
I need to display the UUID in the C# format since other programs already display the UUIDs with the C# format.
In case it might be useful, the example data is stored in MongoDB like this:
BinData(3,"GAElHwsix0a41iIsvQMT8A==")
I need a solution in Java.

Guid is represented by 16 bytes. For various reasons, both Java and .NET do not just print those bytes in order when you call toString. For example, if we look at base-64 encoded guid from your question:
GAElHwsix0a41iIsvQMT8A==
In hex form it will look like this:
18-01-25-1f-0b-22-c7-46-b8-d6-22-2c-bd-03-13-f0
Java toString produces this (if we format as above):
46-c7-22-0b-1f-25-01-18-f0-13-03-bd-2c-22-d6-b8
.NET ToString produces this:
1f-25-01-18-22-0b-46-c7-b8-d6-22-2c-bd-03-13-f0
If you look at this for some time - you will notice that both java and .NET strings represent the same 16 bytes, but positions of those bytes in output string are different. So to convert from java representation to .NET you just need to reorder them. Sample code (I don't know java, so probably it could be done in a better way, but still should achieve the desired result):
static String GetStringFromUuid (java.util.UUID myUuid){
byte[] bytes = new byte[16];
// convert uuid to byte array
ByteBuffer bb = ByteBuffer.wrap(bytes);
bb.putLong(myUuid.getMostSignificantBits());
bb.putLong(myUuid.getLeastSignificantBits());
// reorder
return String.format("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
bytes[4],bytes[5],bytes[6],bytes[7],
bytes[2],bytes[3],bytes[0],bytes[1],
bytes[15],bytes[14],bytes[13],bytes[12],
bytes[11],bytes[10],bytes[9],bytes[8]);
}

We can just keep the GUID as string, if the c# function is receiving the string and it needs to be displayed or sent to some service as string
Just in case if you want to parse it.
You can use the link for GUID parsing logic example
For creating new GUID in C#, use
var guid = System.Guid.NewGuid();
var guidString = guid.ToString();
For creating new UUID in Java, use
UUID uuid = java.util.UUID.randomUUID();
String uuidString = uuid.toString();

Related

What is the correct format for the API SurveyQuestionImage.Data field?

I am working with the GCS API, attempting to create a survey with image data.
I am using the NuGet package Google.Apis.ConsumerSurveys.v2 version 1.14.0.564 on the .Net platform. I can create surveys that do not contain image data without problem. However, when I try to create a survey with image data I receive an error from the API.
I have on hand base64 encoded png format image data. My images display properly in an IMG tag on a web page when the src attribute is set to
'data:image/png;base64,<image base64 string>'
I want to send this image data to the API to populate the survey image. My understanding is that I need to set the Data property of the Google.Apis.ConsumerSurveys.v2.Data.SurveyQuestionImage object to a string containing the image data. I have not been successful.
I first decode my base64 string to a byte array:
byte[] bytes = Convert.FromBase64String(<image base64 string>);
I have tried setting the Data property in the SurveyQuestionImage object as:
image.Data = Encoding.Unicode.GetString(bytes);
This results in this error from the API:
Google.Apis.Requests.RequestError Invalid value for ByteString: <the Data string>
I have also tried converting the byte array to a hexadecimal encoded string as:
StringBuilder sb = new StringBuilder(bytes.Length);
foreach (Byte b in bytes)
{
sb.Append(b.ToString("X2"));
}
image.Data = sb.ToString();
This results in the more hopeful error:
Google.Apis.Requests.RequestError Invalid Value supplied to API: image_data was bad. Request Id: 579665c300ff05e6c316a09e600001737e3430322d747269616c320001707573682d30372d32322d72313000010112 [400] Errors [ Message[Invalid Value supplied to API: image_data was bad. Request Id: 579665c300ff05e6c316a09e600001737e3430322d747269616c320001707573682d30372d32322d72313000010112] Location[ - ] Reason[INVALID_VALUE] Domain[global] ]
Does anyone know the correct format for the Data property of the Google.Apis.ConsumerSurveys.v2.Data.SurveyQuestionImage object?
The data needs to be base64 encoded and also "urlsafe" or "websafe" depending on what language you are using. (python and java, respectively)
In other words, you'll need to first base64 encode then:
Web safe encoding uses '-' instead of '+', '_' instead of '/'
Hope this helps!
For c# users, check out this technique for making websafe b64:
How to achieve Base64 URL safe encoding in C#?
For .net users, look at the comments in this question:
Converting string to web-safe Base64 format
And also this link for more info about .net specific options for encoding:
http://www.codeproject.com/Tips/76650/Base-base-url-base-url-and-z-base-encoding
And to specifically answer the original poster, try this for converting your byte array to a string.
public static string ToBase64ForUrlString(byte[] input)
{
StringBuilder result = new StringBuilder(Convert.ToBase64String(input).TrimEnd('='));
result.Replace('+', '-');
result.Replace('/', '_');
return result.ToString();
}

converting String to ASCII--> BASE64

I'm writing a REST client from a C# usage example. Now i need to convert a string in the proper format but can't find the equivalent method on Java.
original:
string Credentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string);
At this point I've done this:
String Credentials = new String(DatatypeConverter.parseBase64Binary(String));
but i still need the ASCII conversion and I'm not sure that the things I've fount will work fine, like: Convert character to ASCII numeric value in java
any clues?
Thank you.
If you're using java 8 you should take a look at its new Base64 class. It will provide you with a Base64.Encoder whose encodeToString(byte[] src) method accepts a byte array and return a base64 encoded String.
String base64 = Base64.getEncoder().encodeToString("I'm a String".getBytes());
System.out.println(base64); // prints SSdtIGEgU3RyaW5n

How can I convert JSON to key value strings for POST

I currently have a PHP page, that I need to port over so that it runs through Java instead of PHP. Part of that conversion requires running a Sha1 conversion onto a string generated by PHP's http-build-query I need to get the exact same string output in Java that PHP would generate.
So for example:
I have a complex JSON object. (syntax is not exact)
{"user":{"name:'Bob Smith',
"age":47,
"sex":'M',
'dob':'5/12/1956'},
'pastimes'['golf', 'opera', 'poker', 'rap'),
'children'['bobby':{'age':12,'sex':'M'},
'sally'{'age':8, 'sex':'F'}],
'CEO'}};
I need to convert it to a keyvalue string such as
user%5Bname%5D=Bob+Smith&user%5Bage%5D=47&user%5Bsex%5D=M&
user%5Bdob%5D=5%2F12%2F1956&pastimes%5B0%5D=golf&pastimes%5B1%5D=opera&
pastimes%5B2%5D=poker&pastimes%5B3%5D=rap&children%5Bbobby%5D%5Bage%5D=12&
children%5Bbobby%5D%5Bsex%5D=M&children%5Bsally%5D%5Bage%5D=8&
children%5Bsally%5D%5Bsex%5D=F&flags_0=CEO
Essentially, I need to do what the http-build-query in PHP does with complex arrays.

NSData to Java String

I've been writing a Web Application recently that interacts with iPhones. The iPhone iphone will actually send information to the server in the form of a plist. So it's not uncommon to see something like...
<key>RandomData</key>
<data>UW31vrxbUTl07PaDRDEln3EWTLojFFmsm7YuRAscirI=</data>
Now I know this data is hashed/encrypted in some fashion. When I open up the plist with an editor (Property List Editor), it shows me a more "human readable" format. For example, the data above would be converted into something like...
<346df5da 3c5b5259 74ecf683 4431249f 711630ba 232c54ac 9bf2ee44 0r1c8ab2>
Any idea what the method of converting it is? Mainly I'm looking to get this into a Java String.
Thanks!
According to our friends at wikipedia, the <data> tag contains Base64 encoded data. So, use your favorite Java "Base64" class to decode (see also this question).
ps. technically, this is neither "hashed" nor "encrypted", simply "encoded". "Hashed" implies a one-way transformation where multiple input values can yield the same output value. "Encrypted" implies the need for a (usually secret) "key" to reverse the encryption. Base64 encoding is simply a way of representing arbitrary binary data using only printable characters.
After base64 decoding it you need to hex encode it. This is what PL Editor is showing you.
So...
<key>SomeData</key>
<data>UW31ejxbelle7PaeRAEen3EWMLojbFmsm7LuRAscirI=</data?
Can be represented with...
byte[] bytes = Base64.decode("UW31ejxbelle7PaeRAEen3EWMLojbFmsm7LuRAscirI=");
BigInteger bigInt = new BigInteger(bytes);
String hexString = bigInt.toString(16);
System.out.println(hexString);
To get...
<516df5aa 3c5b5259 74ecf683 4401259f 711630ba 236c59ac 9bb2ee44 0b1c8ab2>

Problem in retrieving a decrypted data

I am working on encryption-decryption program.
Program gets an input from the user and encrypts it. Then it stores the encrypted data in ms access database table.
Later, the data is retrieved from the table , decrypted and given back to the user.
I am storing the data as text in the ms access. The encryption algorithm returns a byte array of size 16.
But when i retrieve the data from the database, i am getting a byte array of size 8 only.
Help me to get through this...
I think the problem is that you are using it as text while it isn't (it is binary data). The halving of the length sounds like a Unicode related issue (i.e. the 'text' is stored as wide with two bytes for character, but retrieved as one byte per character).
I have an app that stores encrypted credit card numbers using the MS Crypto interface. I got the code from the MS Knowledge Base, and the key thing is running ByteToString() and StringToByte() conversion in the proper places. I'm storing the actual data in a plain Jet text field and have had no problems whatsoever.
one possible solution is to encode the cipher text as String using Base64 encoding
you can use Appache Commons Library for that:
http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html
Edited:
i dont know why you want MS-ACCESS Specific solution ! the DMBS may change, the OS also may change.. you must to write general solution that can work in many cases..
here small example for using Base64 Encoder/Decoder:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.IOException ;
public class Decoder {
public static void main(String[] args) throws IOException{
byte[] cipherBytes = "stackoverflow".getBytes(); // say this the is encrypted bytes
String encodedBytes = new BASE64Encoder().encode(cipherBytes);
System.out.println("stored as: " + encodedBytes );
byte[] decodedBytes = new BASE64Decoder().decodeBuffer(encodedBytes);
System.out.println("extracted as: " + new String(decodedBytes) );
}
}
Note: this code using Internal Sun Classes (BASE64Encoder/Decoder) and its not recommended to use these classes in your program because it may change in the next version of JDK.
using BASE64 Encoder/Decoder in Appache Commons is better.
if you want the MS-ACCESS solution, try to store the ciphertext in LONGBINARY , see this:
How to specify blob type in MS Access?

Categories