mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 04:58:45 +00:00
Use the new avatar color hash algorithm.
This commit is contained in:
committed by
Michelle Tang
parent
19bf6f95c7
commit
f0f25ae12e
@@ -5,7 +5,9 @@
|
||||
|
||||
package org.thoughtcrime.securesms.conversation.colors
|
||||
|
||||
import org.signal.core.util.CryptoUtil
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
|
||||
/**
|
||||
* Stolen from iOS. Utilizes a simple hash to map different characteristics to an avatar color index.
|
||||
@@ -17,13 +19,13 @@ object AvatarColorHash {
|
||||
*
|
||||
* Uppercase is necessary here because iOS utilizes uppercase UUIDs by default.
|
||||
*/
|
||||
fun forAddress(serviceId: String?, e164: String?): AvatarColor {
|
||||
if (!serviceId.isNullOrEmpty()) {
|
||||
return forSeed(serviceId.toString().uppercase())
|
||||
fun forAddress(serviceId: ServiceId?, e164: String?): AvatarColor {
|
||||
if (serviceId != null) {
|
||||
return forData(serviceId.toByteArray())
|
||||
}
|
||||
|
||||
if (!e164.isNullOrEmpty()) {
|
||||
return forSeed(e164)
|
||||
return forData(e164.toByteArray(Charsets.UTF_8))
|
||||
}
|
||||
|
||||
return AvatarColor.A100
|
||||
@@ -33,22 +35,15 @@ object AvatarColorHash {
|
||||
return forData(group.decodedId)
|
||||
}
|
||||
|
||||
fun forSeed(seed: String): AvatarColor {
|
||||
return forData(seed.toByteArray())
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun forCallLink(rootKey: ByteArray): AvatarColor {
|
||||
return forIndex(rootKey.first().toInt())
|
||||
}
|
||||
|
||||
private fun forData(data: ByteArray): AvatarColor {
|
||||
var hash = 0
|
||||
for (value in data) {
|
||||
hash = hash.rotateLeft(3) xor value.toInt()
|
||||
}
|
||||
|
||||
return forIndex(hash)
|
||||
val hash = CryptoUtil.sha256(data)
|
||||
val firstByte: Byte = hash[0]
|
||||
return forIndex(firstByte.toInt())
|
||||
}
|
||||
|
||||
private fun forIndex(index: Int): AvatarColor {
|
||||
|
||||
@@ -4098,7 +4098,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
PNI_COLUMN to pni?.toString(),
|
||||
PNI_SIGNATURE_VERIFIED to pniVerified.toInt(),
|
||||
STORAGE_SERVICE_ID to Base64.encodeWithPadding(StorageSyncHelper.generateKey()),
|
||||
AVATAR_COLOR to AvatarColorHash.forAddress((aci ?: pni)?.toString(), e164).serialize()
|
||||
AVATAR_COLOR to AvatarColorHash.forAddress((aci ?: pni), e164).serialize()
|
||||
)
|
||||
|
||||
if (pni != null || aci != null) {
|
||||
@@ -4155,7 +4155,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
}
|
||||
|
||||
if (isInsert) {
|
||||
put(AVATAR_COLOR, AvatarColorHash.forAddress(contact.proto.signalAci?.toString() ?: contact.proto.signalPni?.toString(), contact.proto.e164).serialize())
|
||||
put(AVATAR_COLOR, AvatarColorHash.forAddress(contact.proto.signalAci ?: contact.proto.signalPni, contact.proto.e164).serialize())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.conversation.colors
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.signal.core.util.Base64
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.whispersystems.signalservice.api.push.ServiceId.ACI
|
||||
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
||||
|
||||
class AvatarColorHashTest {
|
||||
|
||||
@Test
|
||||
fun `hash test vector - ACI`() {
|
||||
assertEquals(AvatarColor.A140, AvatarColorHash.forAddress(ACI.parseOrThrow("a025bf78-653e-44e0-beb9-deb14ba32487"), null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `hash test vector - PNI`() {
|
||||
assertEquals(AvatarColor.A200, AvatarColorHash.forAddress(PNI.parseOrThrow("11a175e3-fe31-4eda-87da-e0bf2a2e250b"), null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `hash test vector - E164`() {
|
||||
assertEquals(AvatarColor.A150, AvatarColorHash.forAddress(null, "+12135550124"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `hash test vector - GroupId`() {
|
||||
assertEquals(AvatarColor.A130, AvatarColorHash.forGroupId(GroupId.V2.push(Base64.decode("BwJRIdomqOSOckHjnJsknNCibCZKJFt+RxLIpa9CWJ4="))))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user