65 lines
2.0 KiB
Dart
65 lines
2.0 KiB
Dart
import 'dart:typed_data';
|
|
|
|
//图片解密:前 100 字节与 key 循环异或
|
|
class ImageCrypto {
|
|
//jpg/png/gif 文件头,都对不上视为加密图
|
|
static final List<Uint8List> _featuresList = [
|
|
Uint8List.fromList([0xff, 0xd8, 0xff]), //jpg,jpeg
|
|
Uint8List.fromList([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]), //png
|
|
Uint8List.fromList([0x47, 0x49, 0x46]), //gif
|
|
];
|
|
|
|
static const int _minLen = 6; //最小字节数
|
|
static const int _encryptedLen = 100; //加密图片的数据长度
|
|
static final Uint8List _decryptKey = Uint8List.fromList('2019ysapp7527'.codeUnits); //加密key
|
|
|
|
static Uint8List? decrypt(Uint8List? imgBytes) {
|
|
if (imgBytes?.isNotEmpty != true) {
|
|
return imgBytes;
|
|
}
|
|
//不足 6 字节视为坏图,抛给调用方走失败(沿用老逻辑比对 6 字节魔数时越界抛错的行为)
|
|
if (imgBytes!.length < _minLen) {
|
|
throw RangeError.range(imgBytes.length, 0, imgBytes.length - 1, 'length');
|
|
}
|
|
if (_isEncrypted(imgBytes)) {
|
|
imgBytes = _xor(imgBytes, _decryptKey, _encryptedLen);
|
|
}
|
|
return imgBytes;
|
|
}
|
|
|
|
static bool _isEncrypted(Uint8List imgBytes) {
|
|
bool isMismatch = false;
|
|
int featuresLen = _featuresList.length;
|
|
for (int i = 0; i < featuresLen; i++) {
|
|
isMismatch = false;
|
|
for (int j = 0; j < _featuresList[i].length; j++) {
|
|
if (_featuresList[i][j] != imgBytes[j]) {
|
|
isMismatch = true;
|
|
break;
|
|
}
|
|
}
|
|
if (isMismatch) {
|
|
continue;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
return isMismatch;
|
|
}
|
|
|
|
//前 length 字节与 key 循环异或(原地修改)
|
|
static Uint8List _xor(Uint8List src, Uint8List key, int length) {
|
|
int srcLen = src.length;
|
|
int keyLen = key.length;
|
|
if (length > srcLen || length <= 0) {
|
|
length = srcLen;
|
|
}
|
|
for (var i = 0; i < length; i += keyLen) {
|
|
for (var j = 0; j < keyLen && i + j < length; j++) {
|
|
src[i + j] ^= key[j];
|
|
}
|
|
}
|
|
return src;
|
|
}
|
|
}
|