That fuck shit the fascists are using
at master 49 lines 1.5 kB view raw
1package org.tm.archive.util; 2 3import androidx.annotation.NonNull; 4 5import org.tm.archive.recipients.Recipient; 6 7import java.math.BigInteger; 8import java.nio.ByteBuffer; 9import java.nio.ByteOrder; 10import java.security.MessageDigest; 11import java.security.NoSuchAlgorithmException; 12import java.util.Arrays; 13import java.util.UUID; 14 15/** 16 * Logic to bucket a user for a given feature flag based on their UUID. 17 */ 18public final class BucketingUtil { 19 20 private BucketingUtil() {} 21 22 /** 23 * Calculate a user bucket for a given feature flag, uuid, and part per modulus. 24 * 25 * @param key Feature flag key (e.g., "research.megaphone.1") 26 * @param uuid Current user's UUID (see {@link Recipient#getServiceId()}) 27 * @param modulus Drives the bucketing parts per N (e.g., passing 1,000,000 indicates bucketing into parts per million) 28 */ 29 public static long bucket(@NonNull String key, @NonNull UUID uuid, long modulus) { 30 MessageDigest digest; 31 try { 32 digest = MessageDigest.getInstance("SHA-256"); 33 } catch (NoSuchAlgorithmException e) { 34 throw new AssertionError(e); 35 } 36 37 digest.update(key.getBytes()); 38 digest.update(".".getBytes()); 39 40 ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]); 41 byteBuffer.order(ByteOrder.BIG_ENDIAN); 42 byteBuffer.putLong(uuid.getMostSignificantBits()); 43 byteBuffer.putLong(uuid.getLeastSignificantBits()); 44 45 digest.update(byteBuffer.array()); 46 47 return new BigInteger(Arrays.copyOfRange(digest.digest(), 0, 8)).mod(BigInteger.valueOf(modulus)).longValue(); 48 } 49}