import 'dart:typed_data'; //图片解密:前 100 字节与 key 循环异或 class ImageCrypto { //jpg/png/gif 文件头,都对不上视为加密图 static final List _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; } }