Add emoji hash function (#343)

* add emojis

* add func

* add tests
This commit is contained in:
Felicio Mununga 2023-02-21 14:26:42 +01:00 committed by GitHub
parent 16edb12048
commit 1faeb69ac1
No known key found for this signature in database
GPG Key ID: 0EB8D75C775AB6F1
4 changed files with 2902 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,9 @@ export type ColorHash = number[][]
const COLOR_HASH_COLORS_COUNT = 32 const COLOR_HASH_COLORS_COUNT = 32
const COLOR_HASH_SEGMENT_MAX_LENGTH = 5 const COLOR_HASH_SEGMENT_MAX_LENGTH = 5
/**
* @see https://github.com/status-im/specs/pull/166 for specs
*/
export function publicKeyToColorHash(publicKey: string): ColorHash { export function publicKeyToColorHash(publicKey: string): ColorHash {
const compressedPublicKey = compressPublicKey(publicKey) const compressedPublicKey = compressPublicKey(publicKey)
@ -34,7 +37,7 @@ export function hexToColorHash(
return colorHash return colorHash
} }
function numberToIndices(number: bigint, base: bigint): bigint[] { export function numberToIndices(number: bigint, base: bigint): bigint[] {
const indices: bigint[] = [] const indices: bigint[] = []
let nextNumber = number let nextNumber = number

View File

@ -0,0 +1,41 @@
import { expect, test } from 'vitest'
import { publicKeyToEmojiHash } from './public-key-to-emoji-hash'
test('should return emoji hash from public key', () => {
expect(
publicKeyToEmojiHash(
'0x04e25da6994ea2dc4ac70727e07eca153ae92bf7609db7befb7ebdceaad348f4fc55bbe90abf9501176301db5aa103fc0eb3bc3750272a26c424a10887db2a7ea8'
)
).toEqual('👦🏽🦹🏻👶🏿🛁🌁🙌🏻🙇🏽‍♂️🙌🏾🤥🐛👩🏽‍🔧🔧⚙️🧒🏽')
expect(
publicKeyToEmojiHash(
'0x0400000000000000000000000000000000000000000000000000000000000000014218F20AE6C646B363DB68605822FB14264CA8D2587FDD6FBC750D587E76A7EE'
)
).toEqual('😀😀😀😀😀😀😀😀😀😀😀😀😀😀')
expect(
publicKeyToEmojiHash(
'0x04000000000000000000000000000000000000000010000000000000000000000033600332D373318ECC2F212A30A5750D2EAC827B6A32B33D326CCF369B12B1BE'
)
).toEqual('😀😀😀😀😀😀😀😀😀😀😀😀😀😃')
expect(
publicKeyToEmojiHash(
'0x040000000000000000000000000000000000000000200000000000000000000000353050BFE33B724E60A0C600FBA565A9B62217B1BD35BF9848F2AB847C598B30'
)
).toEqual('😀😀😀😀😀😀😀😀😀😀😀😀😀😄')
})
test('should throw for invalid public keys', () => {
expect(() => publicKeyToEmojiHash('abc')).toThrow()
expect(() => publicKeyToEmojiHash('0x01')).toThrow()
expect(() =>
publicKeyToEmojiHash(
'0x01e25da6994ea2dc4ac70727e07eca153ae92bf7609db7befb7ebdceaad348f4fc55bbe90abf9501176301db5aa103fc0eb3bc3750272a26c424a10887db2a7ea8'
)
).toThrow()
expect(() =>
publicKeyToEmojiHash(
'0x04425da6994ea2dc4ac70727e07eca153ae92bf7609db7befb7ebdceaad348f4fc55bbe90abf9501176301db5aa103fc0eb3bc3750272a26c424a10887db2a7ea8'
)
).toThrow()
})

View File

@ -0,0 +1,55 @@
import { emojis } from '../consts/emojis'
import { compressPublicKey } from './compress-public-key'
import { numberToIndices } from './public-key-to-color-hash'
const MIN_EMOJI_HASH_EMOJIS_COUNT = 2757
const EMOJI_HASH_LENGTH = 14
/**
* @see https://github.com/status-im/specs/pull/166 for specs
*/
export function publicKeyToEmojiHash(publicKey: string): string {
if (emojis.length < MIN_EMOJI_HASH_EMOJIS_COUNT) {
throw new Error('Not enough emojis')
}
const compressedPublicKeyHex = compressPublicKey(publicKey)
const emojiHashHex = compressedPublicKeyHex.slice(3, 43)
const emojiHash = hexToEmojiHash(
emojiHashHex,
MIN_EMOJI_HASH_EMOJIS_COUNT,
EMOJI_HASH_LENGTH
)
return emojiHash
}
export function hexToEmojiHash(
hex: string,
emojisCount: number,
hashLength: number
): string {
const emojiIndices = numberToIndices(BigInt(`0x${hex}`), BigInt(emojisCount))
const emojiHash = emojiIndicesToEmojiHash(emojiIndices, hashLength)
return emojiHash
}
function emojiIndicesToEmojiHash(emojiIndices: bigint[], hashLength: number) {
let emojiHash = ''
if (emojiIndices.length < hashLength) {
let fillerIndices = hashLength - emojiIndices.length
while (fillerIndices--) {
emojiIndices.unshift(BigInt(0))
}
}
for (const i of emojiIndices) {
emojiHash += emojis[Number(i)]
}
return emojiHash
}