pref: CUID 生成

This commit is contained in:
HuanCheng65 2023-01-27 20:57:51 +08:00
parent ede1694863
commit 91c4a6caf1
No known key found for this signature in database
GPG Key ID: E9031EF91A805148
17 changed files with 1180 additions and 165 deletions

Binary file not shown.

View File

@ -40,10 +40,10 @@ import com.huanchengfly.tieba.post.utils.EmoticonManager
import com.huanchengfly.tieba.post.utils.SharedPreferencesUtil
import com.huanchengfly.tieba.post.utils.ThemeUtil
import com.huanchengfly.tieba.post.utils.TiebaUtil
import com.huanchengfly.tieba.post.utils.UIDUtil
import com.huanchengfly.tieba.post.utils.Util
import com.huanchengfly.tieba.post.utils.appPreferences
import com.huanchengfly.tieba.post.utils.applicationMetaData
import com.huanchengfly.tieba.post.utils.helios.Base32
import com.huanchengfly.tieba.post.utils.launchUrl
import com.microsoft.appcenter.AppCenter
import com.microsoft.appcenter.analytics.Analytics
@ -65,9 +65,7 @@ class App : Application(), IApp, IGetter, SketchFactory {
private val mActivityList: MutableList<Activity> = mutableListOf()
override fun onOAIDGetComplete(result: String) {
oaid = UIDUtil.Encoder(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="
).encode(result.encodeToByteArray())
oaid = Base32.encode(result.encodeToByteArray())
}
override fun onOAIDGetError(error: Exception) {

View File

@ -1,7 +1,6 @@
package com.huanchengfly.tieba.post.api.retrofit
import android.os.Build
import android.webkit.WebView
import com.huanchengfly.tieba.post.App
import com.huanchengfly.tieba.post.api.Header
import com.huanchengfly.tieba.post.api.Param
@ -47,7 +46,8 @@ object RetrofitTiebaApi {
internal val randomClientId = "wappc_${initTime}_${(Math.random() * 1000).roundToInt()}"
private val stParamInterceptor = StParamInterceptor()
private val connectionPool = ConnectionPool(32, 5, TimeUnit.MINUTES)
private val defaultUserAgent = WebView(App.INSTANCE).settings.userAgentString
private val defaultUserAgent: String =
"Mozilla/5.0 (Linux; Android ${Build.VERSION.RELEASE}; ${Build.MODEL} Build/TKQ1.220829.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.86 Mobile Safari/537.36"
private val defaultCommonParamInterceptor = CommonParamInterceptor(
Param.BDUSS to { AccountUtil.getBduss() },
@ -74,10 +74,10 @@ object RetrofitTiebaApi {
defaultCommonHeaderInterceptor,
CommonHeaderInterceptor(
Header.USER_AGENT to { "bdtb for Android 8.2.2" },
Header.CUID to { UIDUtil.getFinalCUID() }
Header.CUID to { UIDUtil.finalCUID }
),
defaultCommonParamInterceptor + CommonParamInterceptor(
Param.CUID to { UIDUtil.getFinalCUID() },
Param.CUID to { UIDUtil.finalCUID },
Param.FROM to { "baidu_appstore" },
Param.CLIENT_VERSION to { "8.2.2" }
),
@ -106,12 +106,12 @@ object RetrofitTiebaApi {
defaultCommonHeaderInterceptor,
CommonHeaderInterceptor(
Header.USER_AGENT to { "bdtb for Android 7.2.0.0" },
Header.CUID to { UIDUtil.getFinalCUID() },
Header.CUID_GALAXY2 to { UIDUtil.getFinalCUID() }
Header.CUID to { UIDUtil.finalCUID },
Header.CUID_GALAXY2 to { UIDUtil.finalCUID }
),
defaultCommonParamInterceptor + CommonParamInterceptor(
Param.CUID to { UIDUtil.getFinalCUID() },
Param.CUID_GALAXY2 to { UIDUtil.getFinalCUID() },
Param.CUID to { UIDUtil.finalCUID },
Param.CUID_GALAXY2 to { UIDUtil.finalCUID },
Param.FROM to { "1021636m" },
Param.CLIENT_VERSION to { "7.2.0.0" },
Param.SUBAPP_TYPE to { "mini" }

View File

@ -0,0 +1,12 @@
package com.huanchengfly.tieba.post.ui.page.search
import androidx.compose.runtime.Composable
import com.ramcosta.composedestinations.annotation.Destination
@Destination
@Composable
fun SearchPage(
searchWord: String? = null
) {
}

View File

@ -0,0 +1,20 @@
package com.huanchengfly.tieba.post.ui.page.search
import com.huanchengfly.tieba.post.models.database.SearchHistory
class SearchViewModel
sealed interface SearchUiIntent {
data class Init(val keyword: String) : SearchUiIntent
data class SubmitKeyword(val keyword: String) : SearchUiIntent
}
sealed interface SearchPartialChange
data class SearchUiState(
val keyword: String = "",
val searchHistories: List<SearchHistory> = emptyList()
)
sealed interface SearchUiEvent

View File

@ -1,12 +1,12 @@
package com.huanchengfly.tieba.post.utils
import com.huanchengfly.tieba.post.utils.helios.Base32
import com.huanchengfly.tieba.post.utils.helios.Hasher
object CuidUtils {
fun getNewCuid(): String {
val cuid = UIDUtil.getCUID()
val b = aid.common.cc.b().y(cuid.encodeToByteArray())
val encode = UIDUtil.Encoder(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="
).encode(b)
val cuid = UIDUtil.cUID
val encode = Base32.encode(Hasher.hash(cuid.toByteArray()))
return "$cuid|V$encode"
}
}

View File

@ -1,148 +0,0 @@
package com.huanchengfly.tieba.post.utils;
import android.annotation.SuppressLint;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import com.huanchengfly.tieba.post.App;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.UUID;
public class UIDUtil {
@SuppressLint("HardwareIds")
public static String getAndroidId() {
return getAndroidId("");
}
@SuppressLint("HardwareIds")
public static String getAndroidId(String defaultValue) {
String androidId = Settings.Secure.getString(App.getINSTANCE().getContentResolver(), Settings.Secure.ANDROID_ID);
return androidId == null ? defaultValue : androidId;
}
public static String getAid() {
String raw = "com.helios" + getAndroidId("000000000") + getUUID();
byte[] bytes = getSHA1(raw);
return aid.ids.a.ag("A00", new Encoder("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=").encode(bytes));
}
public static byte[] getSHA1(String str) {
byte[] sha1 = null;
try {
MessageDigest digest = MessageDigest.getInstance("SHA1");
sha1 = digest.digest(str.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
e.printStackTrace();
}
return sha1;
}
public static String getNewCUID() {
return "baidutiebaapp" + getUUID();
}
public static String getCUID() {
String androidId = getAndroidId();
String imei = MobileInfoUtil.getIMEI(App.getINSTANCE());
if (TextUtils.isEmpty(imei)) {
imei = "0";
}
return MD5Util.toMd5((Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? imei + androidId + getUUID() : "com.baidu" + androidId).getBytes()).toUpperCase();
}
public static String getFinalCUID() {
String imei = MobileInfoUtil.getIMEI(App.getINSTANCE());
if (TextUtils.isEmpty(imei)) {
imei = "0";
}
return getCUID() + "|" + new StringBuffer(imei).reverse();
}
@SuppressLint("ApplySharedPref")
public static String getUUID() {
String uuid = SharedPreferencesUtil.get(App.getINSTANCE(), SharedPreferencesUtil.SP_APP_DATA)
.getString("uuid", null);
if (uuid == null) {
uuid = UUID.randomUUID().toString();
SharedPreferencesUtil.get(App.getINSTANCE(), SharedPreferencesUtil.SP_APP_DATA)
.edit()
.putString("uuid", uuid)
.apply();
}
return uuid;
}
public static class Encoder {
private final String secret;
public Encoder(String secret) {
this.secret = secret;
}
private static int dt(int var0) {
byte var1;
switch (var0) {
case 1:
var1 = 6;
break;
case 2:
var1 = 4;
break;
case 3:
var1 = 3;
break;
case 4:
var1 = 1;
break;
case 5:
var1 = 0;
break;
default:
var1 = -1;
}
return var1;
}
public String encode(byte[] bytes) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
for (int i = 0; i < (bytes.length + 4) / 5; ++i) {
short[] shorts = new short[5];
int[] ints = new int[8];
int i1 = 0;
int i2;
for (i2 = 5; i1 < 5; ++i1) {
if (i * 5 + i1 < bytes.length) {
shorts[i1] = (short) (bytes[i * 5 + i1] & 255);
} else {
shorts[i1] = 0;
--i2;
}
}
int dt = dt(i2);
ints[0] = (byte) (shorts[0] >> 3 & 31);
ints[1] = (byte) ((shorts[0] & 7) << 2 | shorts[1] >> 6 & 3);
ints[2] = (byte) (shorts[1] >> 1 & 31);
ints[3] = (byte) ((shorts[1] & 1) << 4 | shorts[2] >> 4 & 15);
ints[4] = (byte) ((shorts[2] & 15) << 1 | shorts[3] >> 7 & 1);
ints[5] = (byte) (shorts[3] >> 2 & 31);
ints[6] = (byte) ((shorts[3] & 3) << 3 | shorts[4] >> 5 & 7);
ints[7] = (byte) (shorts[4] & 31);
for (i1 = 0; i1 < ints.length - dt; ++i1) {
outputStream.write(this.secret.charAt(ints[i1]));
}
}
return outputStream.toString();
}
}
}

View File

@ -0,0 +1,86 @@
package com.huanchengfly.tieba.post.utils
import android.annotation.SuppressLint
import android.os.Build
import android.provider.Settings
import android.text.TextUtils
import com.huanchengfly.tieba.post.App.Companion.INSTANCE
import com.huanchengfly.tieba.post.utils.helios.Base32
import com.huanchengfly.tieba.post.utils.helios.Hasher
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import java.util.Locale
import java.util.UUID
object UIDUtil {
@get:SuppressLint("HardwareIds")
val androidId: String
get() = getAndroidId("")
@SuppressLint("HardwareIds")
fun getAndroidId(defaultValue: String): String {
val androidId =
Settings.Secure.getString(INSTANCE.contentResolver, Settings.Secure.ANDROID_ID)
return androidId ?: defaultValue
}
fun getAid(): String {
val raw = "com.helios" + getAndroidId("000000000") + uUID
val bytes = getSHA1(raw)
val encoded = Base32.encode(bytes)
val rawAid = "A00-$encoded-"
val sign = Base32.encode(Hasher.hash(rawAid.toByteArray()))
return "$rawAid$sign"
}
private fun getSHA1(str: String): ByteArray {
var sha1: ByteArray = "".toByteArray()
try {
val digest = MessageDigest.getInstance("SHA1")
sha1 = digest.digest(str.toByteArray(StandardCharsets.UTF_8))
} catch (e: Exception) {
e.printStackTrace()
}
return sha1
}
val newCUID: String
get() = "baidutiebaapp$uUID"
val cUID: String
get() {
val androidId = androidId
var imei = MobileInfoUtil.getIMEI(INSTANCE)
if (TextUtils.isEmpty(imei)) {
imei = "0"
}
return MD5Util.toMd5((if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) imei + androidId + uUID else "com.baidu$androidId").toByteArray())
.uppercase(
Locale.getDefault()
)
}
val finalCUID: String
get() {
var imei = MobileInfoUtil.getIMEI(INSTANCE)
if (TextUtils.isEmpty(imei)) {
imei = "0"
}
return cUID + "|" + StringBuffer(imei).reverse()
}
@get:SuppressLint("ApplySharedPref")
val uUID: String
get() {
var uuid = SharedPreferencesUtil.get(INSTANCE, SharedPreferencesUtil.SP_APP_DATA)
.getString("uuid", null)
if (uuid == null) {
uuid = UUID.randomUUID().toString()
SharedPreferencesUtil.get(INSTANCE, SharedPreferencesUtil.SP_APP_DATA)
.edit()
.putString("uuid", uuid)
.apply()
}
return uuid
}
}

View File

@ -0,0 +1,54 @@
package com.huanchengfly.tieba.post.utils.helios
import java.io.ByteArrayOutputStream
object Base32 {
fun encode(bytes: ByteArray): String {
val outputStream = ByteArrayOutputStream()
for (i in 0 until (bytes.size + 4) / 5) {
val shorts = ShortArray(5)
val ints = IntArray(8)
var i1 = 0
var i2 = 5
while (i1 < 5) {
if (i * 5 + i1 < bytes.size) {
shorts[i1] = (bytes[i * 5 + i1].toInt() and 255).toShort()
} else {
shorts[i1] = 0
--i2
}
++i1
}
val dt = transformInt(i2)
ints[0] = (shorts[0].toInt() shr 3 and 31).toByte().toInt()
ints[1] =
(shorts[0].toInt() and 7 shl 2 or (shorts[1].toInt() shr 6 and 3)).toByte().toInt()
ints[2] = (shorts[1].toInt() shr 1 and 31).toByte().toInt()
ints[3] =
(shorts[1].toInt() and 1 shl 4 or (shorts[2].toInt() shr 4 and 15)).toByte().toInt()
ints[4] =
(shorts[2].toInt() and 15 shl 1 or (shorts[3].toInt() shr 7 and 1)).toByte().toInt()
ints[5] = (shorts[3].toInt() shr 2 and 31).toByte().toInt()
ints[6] =
(shorts[3].toInt() and 3 shl 3 or (shorts[4].toInt() shr 5 and 7)).toByte().toInt()
ints[7] = (shorts[4].toInt() and 31).toByte().toInt()
i1 = 0
while (i1 < ints.size - dt) {
outputStream.write(ALPHABET[ints[i1]].code)
++i1
}
}
return outputStream.toString()
}
private const val ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="
private fun transformInt(i: Int): Int = when (i) {
1 -> 6
2 -> 4
3 -> 3
4 -> 1
5 -> 0
else -> -1
}
}

View File

@ -0,0 +1,40 @@
package com.huanchengfly.tieba.post.utils.helios;
import java.util.Arrays;
class ByteArrayUtils {
public static void copyArray(byte[] dest, byte[] src, int destPos) {
if (destPos < 0) {
throw new IllegalArgumentException("start should be more than zero!");
} else if (dest != null && dest.length != 0) {
if (src != null && src.length != 0) {
if (dest.length < src.length) {
throw new IllegalArgumentException("dst array length should be longer than:" + src.length);
} else {
int length = src.length;
if (dest.length < length + destPos) {
throw new IllegalArgumentException("start should be less than:" + (dest.length - src.length));
} else {
System.arraycopy(src, 0, dest, destPos, src.length);
}
}
} else {
throw new IllegalArgumentException("src array should not be null or empty");
}
} else {
throw new IllegalArgumentException("dst array should not be null or empty");
}
}
public static byte[] copyArray(byte[] src, int newLength) {
if (src != null && src.length != 0) {
if (newLength < 0) {
throw new IllegalArgumentException("length should be more than zero!");
} else {
return Arrays.copyOf(src, newLength);
}
} else {
throw new IllegalArgumentException("original array should not be null or empty");
}
}
}

View File

@ -0,0 +1,24 @@
package com.huanchengfly.tieba.post.utils.helios;
import java.util.zip.CRC32;
final class CRC32Encoder extends IEncoder {
public CRC32Encoder(int start, int flag) {
this.length = 32;
this.start = start;
this.flag = flag;
}
public EncodeResult encode(byte[] bytes, int off, int len) {
long result;
try {
CRC32 crc32 = new CRC32();
crc32.update(bytes, off, len);
result = crc32.getValue();
} catch (Exception var9) {
result = 4294967295L;
}
return EncodeResult.a(new long[]{result});
}
}

View File

@ -0,0 +1,712 @@
package com.huanchengfly.tieba.post.utils.helios;
import androidx.annotation.NonNull;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.LongBuffer;
import java.util.Arrays;
public class EncodeResult implements Serializable, Cloneable {
static final boolean a;
static {
a = !EncodeResult.class.desiredAssertionStatus();
}
private long[] g;
private transient int h = 0;
private transient boolean i = false;
public EncodeResult() {
this.j(64);
this.i = false;
}
public EncodeResult(int bits) {
if (bits < 0) {
throw new NegativeArraySizeException("nbits < 0: " + bits);
} else {
this.j(bits);
this.i = true;
}
}
private EncodeResult(long[] var1) {
this.g = var1;
this.h = var1.length;
this.h();
}
public static EncodeResult a(ByteBuffer var0) {
int var1 = 0;
ByteBuffer var2 = var0.slice().order(ByteOrder.LITTLE_ENDIAN);
int var3 = var2.remaining();
while (var3 > 0 && var2.get(var3 - 1) == 0) --var3;
long[] var5 = new long[(var3 + 7) / 8];
var2.limit(var3);
for (var3 = 0; var2.remaining() >= 8; ++var3) {
var5[var3] = var2.getLong();
}
for (int var4 = var2.remaining(); var1 < var4; ++var1) {
var5[var3] |= ((long) var2.get() & 255L) << var1 * 8;
}
return new EncodeResult(var5);
}
public static EncodeResult a(LongBuffer var0) {
var0 = var0.slice();
int var1 = var0.remaining();
while (var1 > 0 && var0.get(var1 - 1) == 0L) --var1;
long[] var2 = new long[var1];
var0.get(var2);
return new EncodeResult(var2);
}
public static EncodeResult a(byte[] var0) {
return a(ByteBuffer.wrap(var0));
}
public static EncodeResult a(long[] var0) {
int var1 = var0.length;
while (var1 > 0 && var0[var1 - 1] == 0) --var1;
return new EncodeResult(Arrays.copyOf(var0, var1));
}
private static void checkIndex(int fromIndex, int toIndex) {
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
} else if (toIndex < 0) {
throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex);
} else if (fromIndex > toIndex) {
throw new IndexOutOfBoundsException("fromIndex: " + fromIndex + " > toIndex: " + toIndex);
}
}
private static int i(int var0) {
return var0 >> 6;
}
private void h() {
if (!a && this.h != 0 && this.g[this.h - 1] == 0L) {
throw new AssertionError();
} else if (!a && this.h > this.g.length) {
throw new AssertionError();
} else if (!a && this.h != this.g.length && this.g[this.h] != 0L) {
throw new AssertionError();
}
}
private void i() {
int var1 = this.h - 1;
while (var1 >= 0 && this.g[var1] == 0L) {
--var1;
}
this.h = var1 + 1;
}
private void j() {
if (this.h != this.g.length) {
this.g = Arrays.copyOf(this.g, this.h);
this.h();
}
}
private void j(int bits) {
this.g = new long[i(bits - 1) + 1];
}
private void k(int var1) {
if (this.g.length < var1) {
var1 = Math.max(this.g.length * 2, var1);
this.g = Arrays.copyOf(this.g, var1);
this.i = false;
}
}
private void l(int var1) {
++var1;
if (this.h < var1) {
this.k(var1);
this.h = var1;
}
}
public void a(int var1) {
if (var1 < 0) {
throw new IndexOutOfBoundsException("bitIndex < 0: " + var1);
} else {
int var2 = i(var1);
this.l(var2);
long[] var3 = this.g;
var3[var2] ^= 1L << var1;
this.i();
this.h();
}
}
public void a(int fromIndex, int toIndex) {
checkIndex(fromIndex, toIndex);
if (fromIndex != toIndex) {
int var3 = i(fromIndex);
int var4 = i(toIndex - 1);
this.l(var4);
long var5 = -1L << fromIndex;
long var7 = -1L >>> -toIndex;
long[] var9 = this.g;
if (var3 == var4) {
var9[var3] ^= var5 & var7;
} else {
var9[var3] ^= var5;
for (fromIndex = var3 + 1; fromIndex < var4; ++fromIndex) {
var9[fromIndex] = ~var9[fromIndex];
}
var9[var4] ^= var7;
}
this.i();
this.h();
}
}
public void a(int fromIndex, int toIndex, boolean var3) {
if (var3) {
this.b(fromIndex, toIndex);
} else {
this.c(fromIndex, toIndex);
}
}
public void a(int var1, boolean var2) {
if (var2) {
this.b(var1);
} else {
this.c(var1);
}
}
public boolean a(EncodeResult var1) {
int var2 = Math.min(this.h, var1.h) - 1;
boolean var3;
while (true) {
if (var2 < 0) {
var3 = false;
break;
}
if ((this.g[var2] & var1.g[var2]) != 0L) {
var3 = true;
break;
}
--var2;
}
return var3;
}
public byte[] a() {
byte var1 = 0;
int var2 = this.h;
byte[] var3;
if (var2 == 0) {
var3 = new byte[0];
} else {
int var4 = (var2 - 1) * 8;
long var5;
for (var5 = this.g[var2 - 1]; var5 != 0L; var5 >>>= 8) {
++var4;
}
byte[] var7 = new byte[var4];
ByteBuffer var8 = ByteBuffer.wrap(var7).order(ByteOrder.LITTLE_ENDIAN);
for (var4 = var1; var4 < var2 - 1; ++var4) {
var8.putLong(this.g[var4]);
}
var5 = this.g[var2 - 1];
while (true) {
var3 = var7;
if (var5 == 0L) {
break;
}
var8.put((byte) ((int) (255L & var5)));
var5 >>>= 8;
}
}
return var3;
}
public void b(int var1) {
if (var1 < 0) {
throw new IndexOutOfBoundsException("bitIndex < 0: " + var1);
} else {
int var2 = i(var1);
this.l(var2);
long[] var3 = this.g;
var3[var2] |= 1L << var1;
this.h();
}
}
public void b(int fromIndex, int toIndex) {
checkIndex(fromIndex, toIndex);
if (fromIndex != toIndex) {
int var3 = i(fromIndex);
int var4 = i(toIndex - 1);
this.l(var4);
long var5 = -1L << fromIndex;
long var7 = -1L >>> -toIndex;
long[] var9 = this.g;
if (var3 == var4) {
var9[var3] |= var5 & var7;
} else {
var9[var3] |= var5;
for (fromIndex = var3 + 1; fromIndex < var4; ++fromIndex) {
this.g[fromIndex] = -1L;
}
var9[var4] |= var7;
}
this.h();
}
}
public void b(EncodeResult var1) {
if (this != var1) {
while (true) {
long[] var2;
int var3;
if (this.h <= var1.h) {
for (var3 = 0; var3 < this.h; ++var3) {
var2 = this.g;
var2[var3] &= var1.g[var3];
}
this.i();
this.h();
break;
}
var2 = this.g;
var3 = this.h - 1;
this.h = var3;
var2[var3] = 0L;
}
}
}
public long[] b() {
return Arrays.copyOf(this.g, this.h);
}
public void c() {
while (this.h > 0) {
long[] var1 = this.g;
int var2 = this.h - 1;
this.h = var2;
var1[var2] = 0L;
}
}
public void c(int var1) {
if (var1 < 0) {
throw new IndexOutOfBoundsException("bitIndex < 0: " + var1);
} else {
int var2 = i(var1);
if (var2 < this.h) {
long[] var3 = this.g;
var3[var2] &= ~(1L << var1);
this.i();
this.h();
}
}
}
public void c(int fromIndex, int toIndex) {
checkIndex(fromIndex, toIndex);
if (fromIndex != toIndex) {
int var3 = i(fromIndex);
if (var3 < this.h) {
int var4 = i(toIndex - 1);
if (var4 >= this.h) {
toIndex = this.d();
var4 = this.h - 1;
}
long var5 = -1L << fromIndex;
long var7 = -1L >>> -toIndex;
long[] var9 = this.g;
if (var3 == var4) {
var9[var3] &= ~(var5 & var7);
} else {
var9[var3] &= ~var5;
for (fromIndex = var3 + 1; fromIndex < var4; ++fromIndex) {
this.g[fromIndex] = 0L;
}
var9[var4] &= ~var7;
}
this.i();
this.h();
}
}
}
public void c(EncodeResult var1) {
if (this != var1) {
int var2 = Math.min(this.h, var1.h);
if (this.h < var1.h) {
this.k(var1.h);
this.h = var1.h;
}
for (int var3 = 0; var3 < var2; ++var3) {
long[] var4 = this.g;
var4[var3] |= var1.g[var3];
}
if (var2 < var1.h) {
System.arraycopy(var1.g, var2, this.g, var2, this.h - var2);
}
this.h();
}
}
@NonNull
public Object clone() {
if (!this.i) {
this.j();
}
try {
EncodeResult var1 = (EncodeResult) super.clone();
var1.g = this.g.clone();
var1.h();
return var1;
} catch (CloneNotSupportedException var2) {
throw new InternalError();
}
}
public int d() {
int var1;
if (this.h == 0) {
var1 = 0;
} else {
var1 = (this.h - 1) * 64 + (64 - Long.numberOfLeadingZeros(this.g[this.h - 1]));
}
return var1;
}
public EncodeResult d(int fromIndex, int toIndex) {
int var3 = 0;
checkIndex(fromIndex, toIndex);
this.h();
int var4 = this.d();
EncodeResult var5;
if (var4 > fromIndex && fromIndex != toIndex) {
int var6 = Math.min(toIndex, var4);
var5 = new EncodeResult(var6 - fromIndex);
int var7 = i(var6 - fromIndex - 1) + 1;
var4 = i(fromIndex);
boolean var13;
var13 = (fromIndex & 63) == 0;
long[] var8;
long var9;
while (var3 < var7 - 1) {
var8 = var5.g;
if (var13) {
var9 = this.g[var4];
} else {
var9 = this.g[var4] >>> fromIndex | this.g[var4 + 1] << -fromIndex;
}
var8[var3] = var9;
++var3;
++var4;
}
var9 = -1L >>> -var6;
var8 = var5.g;
if ((var6 - 1 & 63) < (fromIndex & 63)) {
long var11 = this.g[var4];
var9 = (var9 & this.g[var4 + 1]) << -fromIndex | var11 >>> fromIndex;
} else {
var9 = (var9 & this.g[var4]) >>> fromIndex;
}
var8[var7 - 1] = var9;
var5.h = var7;
var5.i();
var5.h();
} else {
var5 = new EncodeResult(0);
}
return var5;
}
public void d(EncodeResult var1) {
int var2 = Math.min(this.h, var1.h);
if (this.h < var1.h) {
this.k(var1.h);
this.h = var1.h;
}
for (int var3 = 0; var3 < var2; ++var3) {
long[] var4 = this.g;
var4[var3] ^= var1.g[var3];
}
if (var2 < var1.h) {
System.arraycopy(var1.g, var2, this.g, var2, var1.h - var2);
}
this.i();
this.h();
}
public boolean d(int var1) {
if (var1 < 0) {
throw new IndexOutOfBoundsException("bitIndex < 0: " + var1);
} else {
this.h();
int var2 = i(var1);
boolean var3;
var3 = var2 < this.h && (this.g[var2] & 1L << var1) != 0L;
return var3;
}
}
public int e(int var1) {
byte var2 = -1;
if (var1 < 0) {
throw new IndexOutOfBoundsException("fromIndex < 0: " + var1);
} else {
this.h();
int var3 = i(var1);
if (var3 >= this.h) {
var1 = var2;
} else {
long var4 = this.g[var3] & -1L << var1;
var1 = var3;
while (true) {
if (var4 != 0L) {
var1 = var1 * 64 + Long.numberOfTrailingZeros(var4);
break;
}
var3 = var1 + 1;
var1 = var2;
if (var3 == this.h) {
break;
}
var4 = this.g[var3];
var1 = var3;
}
}
return var1;
}
}
public void e(EncodeResult var1) {
for (int var2 = Math.min(this.h, var1.h) - 1; var2 >= 0; --var2) {
long[] var3 = this.g;
var3[var2] &= ~var1.g[var2];
}
this.i();
this.h();
}
public boolean e() {
return this.h == 0;
}
public boolean equals(Object var1) {
boolean var2 = false;
boolean var3;
if (!(var1 instanceof EncodeResult)) {
var3 = var2;
} else if (this == var1) {
var3 = true;
} else {
EncodeResult var5 = (EncodeResult) var1;
this.h();
var5.h();
var3 = var2;
if (this.h == var5.h) {
int var4 = 0;
while (true) {
if (var4 >= this.h) {
var3 = true;
break;
}
if (this.g[var4] != var5.g[var4]) {
break;
}
++var4;
}
}
}
return var3;
}
public int f() {
int var1 = 0;
int var2;
for (var2 = 0; var1 < this.h; ++var1) {
var2 += Long.bitCount(this.g[var1]);
}
return var2;
}
public int f(int var1) {
if (var1 < 0) {
throw new IndexOutOfBoundsException("fromIndex < 0: " + var1);
} else {
this.h();
int var2 = i(var1);
if (var2 < this.h) {
long var3 = ~this.g[var2] & -1L << var1;
for (var1 = var2; var3 == 0L; var3 = ~this.g[var1]) {
++var1;
if (var1 == this.h) {
var1 = this.h * 64;
return var1;
}
}
var1 = var1 * 64 + Long.numberOfTrailingZeros(var3);
}
return var1;
}
}
public int h(int var1) {
int var2;
if (var1 < 0) {
if (var1 != -1) {
throw new IndexOutOfBoundsException("fromIndex < -1: " + var1);
}
var2 = -1;
} else {
this.h();
int var3 = i(var1);
var2 = var1;
if (var3 < this.h) {
long var4 = ~this.g[var3] & -1L >>> -(var1 + 1);
for (var1 = var3; var4 == 0L; var1 = var2) {
var2 = var1 - 1;
if (var1 == 0) {
var2 = -1;
return var2;
}
var4 = ~this.g[var2];
}
var2 = (var1 + 1) * 64 - 1 - Long.numberOfLeadingZeros(var4);
}
}
return var2;
}
public int hashCode() {
long var1 = 1234L;
int var3 = this.h;
while (true) {
--var3;
if (var3 < 0) {
return (int) (var1 >> 32 ^ var1);
}
var1 ^= this.g[var3] * (long) (var3 + 1);
}
}
@NonNull
public String toString() {
this.h();
int var1;
if (this.h > 128) {
var1 = this.f();
} else {
var1 = this.h * 64;
}
StringBuilder var2 = new StringBuilder(var1 * 6 + 2);
var2.append('{');
var1 = this.e(0);
if (var1 != -1) {
var2.append(var1);
int var4;
for (var1 = this.e(var1 + 1); var1 >= 0; var1 = this.e(var4 + 1)) {
int var3 = this.f(var1);
do {
var2.append(", ").append(var1);
var4 = var1 + 1;
var1 = var4;
} while (var4 < var3);
}
}
var2.append('}');
return var2.toString();
}
}

View File

@ -0,0 +1,38 @@
package com.huanchengfly.tieba.post.utils.helios;
class HashResult {
public static int BITS = 40;
private final EncodeResult mEncodeResult;
public HashResult() {
this.mEncodeResult = new EncodeResult(BITS);
this.mEncodeResult.a(0, BITS, true);
}
public void update(EncodeResult var1, int start, int length, int var4) {
EncodeResult var5 = this.mEncodeResult.d(start, start + length);
switch (var4) {
case 0:
var5.b(var1);
break;
case 2:
var5.e(var1);
break;
case 3:
var5.c(var1);
break;
case 1:
default:
var5.d(var1);
}
for (var4 = 0; var4 < length; ++var4) {
this.mEncodeResult.a(start + var4, var5.d(var4));
}
}
public byte[] getValue() {
return this.mEncodeResult.a();
}
}

View File

@ -0,0 +1,22 @@
package com.huanchengfly.tieba.post.utils.helios;
import java.util.Arrays;
public class Hasher {
static IEncoder[] sEncoders = new IEncoder[]{new CRC32Encoder(8, 0), new XXHashEncoder(0, 1), new XXHashEncoder(1, 1), new CRC32Encoder(7, 1)};
public static byte[] hash(byte[] bytes) {
HashResult result = new HashResult();
byte[] newBytes = ByteArrayUtils.copyArray(bytes, bytes.length + (sEncoders.length + 1) * 5);
ByteArrayUtils.copyArray(newBytes, result.getValue(), bytes.length);
for (int i = 0; i < sEncoders.length; i++) {
IEncoder encoder = sEncoders[i];
int len = bytes.length + (i + 1) * 5;
result.update(encoder.encode(newBytes, 0, len), encoder.getStart(), encoder.getLength(), encoder.getFlag());
ByteArrayUtils.copyArray(newBytes, result.getValue(), len);
}
return Arrays.copyOf(result.getValue(), 5);
}
}

View File

@ -0,0 +1,24 @@
package com.huanchengfly.tieba.post.utils.helios;
abstract class IEncoder {
protected int length = 32;
protected int start;
protected int flag;
IEncoder() {
}
public int getStart() {
return this.start;
}
public int getLength() {
return this.length;
}
public int getFlag() {
return this.flag;
}
public abstract EncodeResult encode(byte[] bytes, int off, int len);
}

View File

@ -0,0 +1,117 @@
package com.huanchengfly.tieba.post.utils.helios;
class XXHash {
private final int[] i;
private final byte[] j;
private final int k;
private int l;
private int m;
protected XXHash() {
this(0);
}
protected XXHash(int var1) {
this.i = new int[4];
this.j = new byte[16];
this.k = var1;
this.c();
}
private static int a(byte[] var0, int var1) {
return (int) (j(var0, var1) & 4294967295L);
}
private static long j(byte[] var0, int var1) {
if (4 > 8) {
throw new IllegalArgumentException("can't read more than eight bytes into a long value");
} else {
long var3 = 0L;
for (int var5 = 0; var5 < 4; ++var5) {
var3 |= ((long) var0[var1 + var5] & 255L) << var5 * 8;
}
return var3;
}
}
private void c() {
this.i[0] = this.k - 1640531535 - 2048144777;
this.i[1] = this.k - 2048144777;
this.i[2] = this.k;
this.i[3] = this.k + 1640531535;
}
private void g(byte[] var1, int var2) {
int var3 = this.i[0];
int var4 = this.i[1];
int var5 = this.i[2];
int var6 = this.i[3];
var3 = Integer.rotateLeft(var3 + a(var1, var2) * -2048144777, 13);
var4 = Integer.rotateLeft(var4 + a(var1, var2 + 4) * -2048144777, 13);
var5 = Integer.rotateLeft(var5 + a(var1, var2 + 8) * -2048144777, 13);
var2 = Integer.rotateLeft(var6 + a(var1, var2 + 12) * -2048144777, 13);
this.i[0] = var3 * -1640531535;
this.i[1] = var4 * -1640531535;
this.i[2] = var5 * -1640531535;
this.i[3] = var2 * -1640531535;
this.m = 0;
}
protected void update(byte[] var1, int var2, int var3) {
if (var3 > 0) {
this.l += var3;
int var4 = var2 + var3;
if (this.m + var3 < 16) {
System.arraycopy(var1, var2, this.j, this.m, var3);
this.m += var3;
} else {
var3 = var2;
if (this.m > 0) {
var3 = 16 - this.m;
System.arraycopy(var1, var2, this.j, this.m, var3);
this.g(this.j, 0);
var3 += var2;
}
while (var3 <= var4 - 16) {
this.g(var1, var3);
var3 += 16;
}
if (var3 < var4) {
this.m = var4 - var3;
System.arraycopy(var1, var3, this.j, 0, this.m);
}
}
}
}
protected long getValue() {
int var1;
if (this.l > 16) {
var1 = Integer.rotateLeft(this.i[0], 1) + Integer.rotateLeft(this.i[1], 7) + Integer.rotateLeft(this.i[2], 12) + Integer.rotateLeft(this.i[3], 18);
} else {
var1 = this.i[2] + 374761393;
}
int var2 = this.l;
int var3 = this.m;
var2 += var1;
for (var1 = 0; var1 <= var3 - 4; var1 += 4) {
var2 = Integer.rotateLeft(var2 + a(this.j, var1) * -1028477379, 17) * 668265263;
}
while (var1 < this.m) {
var2 = Integer.rotateLeft((this.j[var1] & 255) * 374761393 + var2, 11) * -1640531535;
++var1;
}
var1 = (var2 >>> 15 ^ var2) * -2048144777;
var1 = (var1 ^ var1 >>> 13) * -1028477379;
return (long) (var1 ^ var1 >>> 16) & 4294967295L;
}
}

View File

@ -0,0 +1,16 @@
package com.huanchengfly.tieba.post.utils.helios;
final class XXHashEncoder extends IEncoder {
public XXHashEncoder(int start, int flag) {
this.length = 32;
this.start = start;
this.flag = flag;
}
public EncodeResult encode(byte[] bytes, int off, int len) {
XXHash xxHash = new XXHash();
xxHash.update(bytes, off, len);
return EncodeResult.a(new long[]{xxHash.getValue()});
}
}