fix UUIDv4 calculation

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/utils/AccountUtils.java | 33 +++--
1 file changed, 19 insertions(+), 14 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/utils/AccountUtils.java 🔗

@@ -6,6 +6,10 @@ import android.view.Menu;
 import android.view.MenuItem;
 import android.widget.Toast;
 
+import com.google.common.primitives.Bytes;
+import com.google.common.primitives.Longs;
+
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
@@ -24,10 +28,9 @@ public class AccountUtils {
         MANAGE_ACCOUNT_ACTIVITY = getManageAccountActivityClass();
     }
 
-
     public static boolean hasEnabledAccounts(final XmppConnectionService service) {
         final List<Account> accounts = service.getAccounts();
-        for(Account account : accounts) {
+        for (Account account : accounts) {
             if (account.isOptionSet(Account.OPTION_DISABLED)) {
                 return false;
             }
@@ -42,19 +45,21 @@ public class AccountUtils {
         } catch (final IllegalArgumentException e) {
             return account.getUuid();
         }
-        final UUID publicDeviceId = getUuid(uuid.getLeastSignificantBits(), uuid.getLeastSignificantBits());
-        return publicDeviceId.toString();
-    }
-
-    protected static UUID getUuid(final long msb, final long lsb) {
-        final long msb0 = (msb & 0xffffffffffff0fffL) | 4; // set version
-        final long lsb0 = (lsb & 0x3fffffffffffffffL) | 0x8000000000000000L; // set variant
-        return new UUID(msb0, lsb0);
+        final byte[] bytes =
+                Bytes.concat(
+                        Longs.toByteArray(uuid.getLeastSignificantBits()),
+                        Longs.toByteArray(uuid.getLeastSignificantBits()));
+        bytes[6] &= 0x0f; /* clear version        */
+        bytes[6] |= 0x40; /* set to version 4     */
+        bytes[8] &= 0x3f; /* clear variant        */
+        bytes[8] |= 0x80; /* set to IETF variant  */
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+        return new UUID(byteBuffer.getLong(), byteBuffer.getLong()).toString();
     }
 
     public static List<String> getEnabledAccounts(final XmppConnectionService service) {
-        ArrayList<String> accounts = new ArrayList<>();
-        for (Account account : service.getAccounts()) {
+        final ArrayList<String> accounts = new ArrayList<>();
+        for (final Account account : service.getAccounts()) {
             if (account.getStatus() != Account.State.DISABLED) {
                 if (Config.DOMAIN_LOCK != null) {
                     accounts.add(account.getJid().getEscapedLocal());
@@ -68,7 +73,7 @@ public class AccountUtils {
 
     public static Account getFirstEnabled(XmppConnectionService service) {
         final List<Account> accounts = service.getAccounts();
-        for(Account account : accounts) {
+        for (Account account : accounts) {
             if (!account.isOptionSet(Account.OPTION_DISABLED)) {
                 return account;
             }
@@ -78,7 +83,7 @@ public class AccountUtils {
 
     public static Account getFirst(XmppConnectionService service) {
         final List<Account> accounts = service.getAccounts();
-        for(Account account : accounts) {
+        for (Account account : accounts) {
             return account;
         }
         return null;