// ==UserScript==
// @name 百度贴吧图片解混淆助手
// @namespace https://greasyfork.org/
// @version 1.4.0
// @description 自动获取帖子原图,支持多种混淆算法,可自定义图片进行混淆,还能一键保存图片。
// @license MIT
// @author Kira Diana
// @match https://tieba.baidu.com/*
// @grant none
// ==/UserScript==
/**
* 此脚本的小番茄混淆代码来源于:https://xfqtphx.netlify.app/
* 其他混淆算法实现来源于:https://www.axe.ink/blog/encrypt/
* 本人对这些代码进行整合,并编写了相关界面代码。
*/
let pic_list = {}
let isOriginalPicPage = false
let SIZE = 4294967296;
let first_config
let defaultTomatoKey = 1
let defaultOtherKey = 0.666
function gilbert2d(width, height) {
/**
* Generalized Hilbert ('gilbert') space-filling curve for arbitrary-sized
* 2D rectangular grids. Generates discrete 2D coordinates to fill a rectangle
* of size (width x height).
*/
const coordinates = [];
if (width >= height) {
generate2d(0, 0, width, 0, 0, height, coordinates);
} else {
generate2d(0, 0, 0, height, width, 0, coordinates);
}
return coordinates;
}
function generate2d(x, y, ax, ay, bx, by, coordinates) {
const w = Math.abs(ax + ay);
const h = Math.abs(bx + by);
const dax = Math.sign(ax), day = Math.sign(ay); // unit major direction
const dbx = Math.sign(bx), dby = Math.sign(by); // unit orthogonal direction
if (h === 1) {
// trivial row fill
for (let i = 0; i < w; i++) {
coordinates.push([x, y]);
x += dax;
y += day;
}
return;
}
if (w === 1) {
// trivial column fill
for (let i = 0; i < h; i++) {
coordinates.push([x, y]);
x += dbx;
y += dby;
}
return;
}
let ax2 = Math.floor(ax / 2), ay2 = Math.floor(ay / 2);
let bx2 = Math.floor(bx / 2), by2 = Math.floor(by / 2);
const w2 = Math.abs(ax2 + ay2);
const h2 = Math.abs(bx2 + by2);
if (2 * w > 3 * h) {
if ((w2 % 2) && (w > 2)) {
// prefer even steps
ax2 += dax;
ay2 += day;
}
// long case: split in two parts only
generate2d(x, y, ax2, ay2, bx, by, coordinates);
generate2d(x + ax2, y + ay2, ax - ax2, ay - ay2, bx, by, coordinates);
} else {
if ((h2 % 2) && (h > 2)) {
// prefer even steps
bx2 += dbx;
by2 += dby;
}
// standard case: one step up, one long horizontal, one step down
generate2d(x, y, bx2, by2, ax2, ay2, coordinates);
generate2d(x + bx2, y + by2, ax, ay, bx - bx2, by - by2, coordinates);
generate2d(x + (ax - dax) + (bx2 - dbx), y + (ay - day) + (by2 - dby),
-bx2, -by2, -(ax - ax2), -(ay - ay2), coordinates);
}
}
function encryptTomato(img, key){
const cvs = document.createElement("canvas")
const width = cvs.width = img.naturalWidth
const height = cvs.height = img.naturalHeight
const ctx = cvs.getContext("2d")
ctx.drawImage(img, 0, 0)
const imgdata = ctx.getImageData(0, 0, width, height)
const imgdata2 = new ImageData(width, height)
const curve = gilbert2d(width, height)
const offset = Math.round((Math.sqrt(5) - 1) / 2 * width * height * parseFloat(key))
for(let i = 0; i < width * height; i++){
const old_pos = curve[i]
const new_pos = curve[(i + offset) % (width * height)]
const old_p = 4 * (old_pos[0] + old_pos[1] * width)
const new_p = 4 * (new_pos[0] + new_pos[1] * width)
imgdata2.data.set(imgdata.data.slice(old_p, old_p + 4), new_p)
}
ctx.putImageData(imgdata2, 0, 0)
cvs.toBlob(b => {
URL.revokeObjectURL(img.src)
img.src = URL.createObjectURL(b)
}, "image/png", 1)
//})
}
function decryptTomato(img, key){
const cvs = document.createElement("canvas")
const width = cvs.width = img.naturalWidth
const height = cvs.height = img.naturalHeight
const ctx = cvs.getContext("2d")
ctx.drawImage(img, 0, 0)
const imgdata = ctx.getImageData(0, 0, width, height)
const imgdata2 = new ImageData(width, height)
const curve = gilbert2d(width, height)
const offset = Math.round((Math.sqrt(5) - 1) / 2 * width * height * parseFloat(key))
for(let i = 0; i < width * height; i++){
const old_pos = curve[i]
const new_pos = curve[(i + offset) % (width * height)]
const old_p = 4 * (old_pos[0] + old_pos[1] * width)
const new_p = 4 * (new_pos[0] + new_pos[1] * width)
imgdata2.data.set(imgdata.data.slice(new_p, new_p + 4), old_p)
}
ctx.putImageData(imgdata2, 0, 0)
cvs.toBlob(b => {
URL.revokeObjectURL(img.src)
img.src = URL.createObjectURL(b)
}, "image/png", 1)
//})
}
var md5 = (function() {
function MD5(string) {
var x = Array();
var k, AA, BB, CC, DD, a, b, c, d;
var S11 = 7
, S12 = 12
, S13 = 17
, S14 = 22;
var S21 = 5
, S22 = 9
, S23 = 14
, S24 = 20;
var S31 = 4
, S32 = 11
, S33 = 16
, S34 = 23;
var S41 = 6
, S42 = 10
, S43 = 15
, S44 = 21;
string = Utf8Encode(string);
x = ConvertToWordArray(string);
a = 0x67452301;
b = 0xEFCDAB89;
c = 0x98BADCFE;
d = 0x10325476;
for (k = 0; k < x.length; k += 16) {
AA = a;
BB = b;
CC = c;
DD = d;
a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
a = AddUnsigned(a, AA);
b = AddUnsigned(b, BB);
c = AddUnsigned(c, CC);
d = AddUnsigned(d, DD);
}
var temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d);
return temp.toUpperCase();
}
function RotateLeft(lValue, iShiftBits) {
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
}
function AddUnsigned(lX, lY) {
var lX4, lY4, lX8, lY8, lResult;
lX8 = (lX & 0x80000000);
lY8 = (lY & 0x80000000);
lX4 = (lX & 0x40000000);
lY4 = (lY & 0x40000000);
lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
if (lX4 & lY4) {
return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
}
if (lX4 | lY4) {
if (lResult & 0x40000000) {
return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
} else {
return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
}
} else {
return (lResult ^ lX8 ^ lY8);
}
}
function F(x, y, z) {
return (x & y) | ((~x) & z);
}
function G(x, y, z) {
return (x & z) | (y & (~z));
}
function H(x, y, z) {
return (x ^ y ^ z);
}
function I(x, y, z) {
return (y ^ (x | (~z)));
}
function FF(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function GG(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function HH(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function II(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}
function ConvertToWordArray(string) {
var lWordCount;
var lMessageLength = string.length;
var lNumberOfWords_temp1 = lMessageLength + 8;
var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
var lWordArray = Array(lNumberOfWords - 1);
var lBytePosition = 0;
var lByteCount = 0;
while (lByteCount < lMessageLength) {
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
lByteCount++;
}
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
return lWordArray;
}
function WordToHex(lValue) {
var WordToHexValue = "", WordToHexValue_temp = "", lByte, lCount;
for (lCount = 0; lCount <= 3; lCount++) {
lByte = (lValue >>> (lCount * 8)) & 255;
WordToHexValue_temp = "0" + lByte.toString(16);
WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
}
return WordToHexValue;
}
function Utf8Encode(string) {
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
return MD5
}())
//随机打乱
function amess(arrlength, ast) {
var rand, temp;
var arr = new Array(arrlength).fill(0).map( (a, b) => b);
for (let i = arrlength - 1; i > 0; i -= 1) {
rand = parseInt(md5(ast + i.toString()).substr(0, 7), 16) % (i + 1);
temp = arr[rand];
arr[rand] = arr[i]
arr[i] = temp;
}
return arr;
}
//块混淆
function encryptB2(img1, key, sx, sy) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var wid1 = wid;
var hit1 = hit;
var imgdata;
var oimgdata;
var xl = new Array();
var yl = new Array();
var k = 8;
var m = 0;
var n = 0;
var ssx;
var ssy;
//缩放大小
if (wid * hit > SIZE) {
wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
}
wid1 = wid;
hit1 = hit;
while (wid % sx > 0) {
wid++
}
while (hit % sy > 0) {
hit++
}
ssx = wid / sx;
ssy = hit / sy;
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid1, hit1);
cvd.drawImage(img1, 0, hit1, wid1, hit1);
cvd.drawImage(img1, wid1, 0, wid1, hit1);
cvd.drawImage(img1, wid1, hit1, wid1, hit1);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
xl = amess(sx, key);
yl = amess(sy, key);
for (let i = 0; i < wid; i++) {
for (let j = 0; j < hit; j++) {
m = i;
n = j;
m = (xl[((n / ssy) | 0) % sx] * ssx + m) % wid;
m = xl[(m / ssx) | 0] * ssx + m % ssx;
n = (yl[((m / ssx) | 0) % sy] * ssy + n) % hit;
n = yl[(n / ssy) | 0] * ssy + n % ssy;
oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + n * wid)];
oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + n * wid) + 1];
oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + n * wid) + 2];
oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + n * wid) + 3];
}
}
cvd.putImageData(oimgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
function decryptB2(img1, key, sx, sy) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var wid1 = wid;
var hit1 = hit;
var imgdata;
var oimgdata;
var xl = new Array();
var yl = new Array();
var k = 8;
var m = 0;
var n = 0;
var ssx;
var ssy;
wid1 = wid;
hit1 = hit;
while (wid % sx > 0) {
wid++
}
while (hit % sy > 0) {
hit++
}
ssx = wid / sx;
ssy = hit / sy;
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid1, hit1);
cvd.drawImage(img1, 0, hit1, wid1, hit1);
cvd.drawImage(img1, wid1, 0, wid1, hit1);
cvd.drawImage(img1, wid1, hit1, wid1, hit1);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
xl = amess(sx, key);
yl = amess(sy, key);
for (let i = 0; i < wid; i++) {
for (let j = 0; j < hit; j++) {
m = i;
n = j;
m = (xl[((n / ssy) | 0) % sx] * ssx + m) % wid;
m = xl[(m / ssx) | 0] * ssx + m % ssx;
n = (yl[((m / ssx) | 0) % sy] * ssy + n) % hit;
n = yl[(n / ssy) | 0] * ssy + n % ssy;
oimgdata.data[4 * (m + n * wid)] = imgdata.data[4 * (i + j * wid)];
oimgdata.data[4 * (m + n * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
oimgdata.data[4 * (m + n * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
oimgdata.data[4 * (m + n * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
}
}
cvd.putImageData(oimgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
//算法C,逐像素混淆
function encryptC(img1, key) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var imgdata;
var oimgdata;
var xl = new Array();
var yl = new Array();
var m = 0;
var n = 0;
//缩放大小
if (wid * hit > SIZE) {
wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
}
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid, hit);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
xl = amess(wid, key);
yl = amess(hit, key);
for (let i = 0; i < wid; i++) {
for (let j = 0; j < hit; j++) {
m = i;
n = j;
m = (xl[n % wid] + m) % wid;
m = xl[m];
n = (yl[m % hit] + n) % hit;
n = yl[n];
oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + n * wid)];
oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + n * wid) + 1];
oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + n * wid) + 2];
oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + n * wid) + 3];
}
}
cvd.putImageData(oimgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
function decryptC(img1, key) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var imgdata;
var oimgdata;
var xl = new Array();
var yl = new Array();
var m = 0;
var n = 0;
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid, hit);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
xl = amess(wid, key);
yl = amess(hit, key);
for (let i = 0; i < wid; i++) {
for (let j = 0; j < hit; j++) {
m = i;
n = j;
m = (xl[n % wid] + m) % wid;
m = xl[m];
n = (yl[m % hit] + n) % hit;
n = yl[n];
oimgdata.data[4 * (m + n * wid)] = imgdata.data[4 * (i + j * wid)];
oimgdata.data[4 * (m + n * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
oimgdata.data[4 * (m + n * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
oimgdata.data[4 * (m + n * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
}
}
cvd.putImageData(oimgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
//行像素混淆
function encryptC2(img1, key) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var imgdata;
var oimgdata;
var xl = new Array();
var yl = new Array();
var m = 0;
var n = 0;
//缩放大小
if (wid * hit > SIZE) {
wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
}
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid, hit);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
xl = amess(wid, key);
yl = amess(hit, key);
for (let i = 0; i < wid; i++) {
for (let j = 0; j < hit; j++) {
m = i;
n = j;
m = (xl[n % wid] + m) % wid;
m = xl[m];
oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + n * wid)];
oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + n * wid) + 1];
oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + n * wid) + 2];
oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + n * wid) + 3];
}
}
cvd.putImageData(oimgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
function decryptC2(img1, key) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var imgdata;
var oimgdata;
var xl = new Array();
var yl = new Array();
var m = 0;
var n = 0;
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid, hit);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
xl = amess(wid, key);
yl = amess(hit, key);
for (let i = 0; i < wid; i++) {
for (let j = 0; j < hit; j++) {
m = i;
n = j;
m = (xl[n % wid] + m) % wid;
m = xl[m];
oimgdata.data[4 * (m + n * wid)] = imgdata.data[4 * (i + j * wid)];
oimgdata.data[4 * (m + n * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
oimgdata.data[4 * (m + n * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
oimgdata.data[4 * (m + n * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
}
}
cvd.putImageData(oimgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
//picencrypt算法
function produceLogisticSort(a, b) {
return a[0] - b[0]
}
function produceLogistic(x1, n) {
let l = new Array(n);
let x = x1;
l[0] = [x, 0];
for (let i = 1; i < n; i++) {
x = 3.9999999 * x * (1 - x);
l[i] = [x, i]
}
return l
}
//行混淆
function encryptPE1(img1, key) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var imgdata;
var oimgdata;
var arrayaddress = new Array();
var m = 0;
var n = 0;
//缩放大小
if (wid * hit > SIZE) {
wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
}
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid, hit);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
arrayaddress = produceLogistic(key, wid).sort(produceLogisticSort).map(x => x[1]);
for (let i = 0; i < wid; i++) {
for (let j = 0; j < hit; j++) {
m = arrayaddress[i];
oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + j * wid)];
oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + j * wid) + 1];
oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + j * wid) + 2];
oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + j * wid) + 3];
}
}
cvd.putImageData(oimgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
function decryptPE1(img1, key) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var imgdata;
var oimgdata;
var arrayaddress = new Array();
var m = 0;
var n = 0;
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid, hit);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
arrayaddress = produceLogistic(key, wid).sort(produceLogisticSort).map(x => x[1]);
for (let i = 0; i < wid; i++) {
for (let j = 0; j < hit; j++) {
m = arrayaddress[i];
oimgdata.data[4 * (m + j * wid)] = imgdata.data[4 * (i + j * wid)];
oimgdata.data[4 * (m + j * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
oimgdata.data[4 * (m + j * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
oimgdata.data[4 * (m + j * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
}
}
cvd.putImageData(oimgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
//行+列混淆
function encryptPE2(img1, key) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var imgdata;
var oimgdata;
var o2imgdata;
var arrayaddress = new Array();
var x = key;
var m = 0;
var n = 0;
if (wid * hit > SIZE) {
wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
}
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid, hit);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
o2imgdata = cvd.createImageData(wid, hit);
for (let j = 0; j < hit; j++) {
arrayaddress = produceLogistic(x, wid);
x = arrayaddress[wid - 1][0];
arrayaddress = arrayaddress.sort(produceLogisticSort).map(a => a[1])
for (let i = 0; i < wid; i++) {
m = arrayaddress[i];
oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + j * wid)];
oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + j * wid) + 1];
oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + j * wid) + 2];
oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + j * wid) + 3];
}
}
x = key;
for (let i = 0; i < wid; i++) {
arrayaddress = produceLogistic(x, hit);
x = arrayaddress[hit - 1][0];
arrayaddress = arrayaddress.sort(produceLogisticSort).map(a => a[1])
for (let j = 0; j < hit; j++) {
n = arrayaddress[j];
o2imgdata.data[4 * (i + j * wid)] = oimgdata.data[4 * (i + n * wid)];
o2imgdata.data[4 * (i + j * wid) + 1] = oimgdata.data[4 * (i + n * wid) + 1];
o2imgdata.data[4 * (i + j * wid) + 2] = oimgdata.data[4 * (i + n * wid) + 2];
o2imgdata.data[4 * (i + j * wid) + 3] = oimgdata.data[4 * (i + n * wid) + 3];
}
}
cvd.putImageData(o2imgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
function decryptPE2(img1, key) {
var cv = document.createElement("canvas");
var cvd = cv.getContext("2d");
var wid = img1.naturalWidth;
var hit = img1.naturalHeight;
var imgdata;
var oimgdata;
var o2imgdata;
var arrayaddress = new Array();
var x = key;
var m = 0;
var n = 0;
cv.width = wid;
cv.height = hit;
cvd.drawImage(img1, 0, 0, wid, hit);
imgdata = cvd.getImageData(0, 0, wid, hit);
oimgdata = cvd.createImageData(wid, hit);
o2imgdata = cvd.createImageData(wid, hit);
for (let i = 0; i < wid; i++) {
arrayaddress = produceLogistic(x, hit);
x = arrayaddress[hit - 1][0];
arrayaddress = arrayaddress.sort(produceLogisticSort).map(a => a[1])
for (let j = 0; j < hit; j++) {
n = arrayaddress[j];
oimgdata.data[4 * (i + n * wid)] = imgdata.data[4 * (i + j * wid)];
oimgdata.data[4 * (i + n * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
oimgdata.data[4 * (i + n * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
oimgdata.data[4 * (i + n * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
}
}
x = key;
for (let j = 0; j < hit; j++) {
arrayaddress = produceLogistic(x, wid);
x = arrayaddress[wid - 1][0];
arrayaddress = arrayaddress.sort(produceLogisticSort).map(a => a[1])
for (let i = 0; i < wid; i++) {
m = arrayaddress[i];
o2imgdata.data[4 * (m + j * wid)] = oimgdata.data[4 * (i + j * wid)];
o2imgdata.data[4 * (m + j * wid) + 1] = oimgdata.data[4 * (i + j * wid) + 1];
o2imgdata.data[4 * (m + j * wid) + 2] = oimgdata.data[4 * (i + j * wid) + 2];
o2imgdata.data[4 * (m + j * wid) + 3] = oimgdata.data[4 * (i + j * wid) + 3];
}
}
cvd.putImageData(o2imgdata, 0, 0);
return [cv.toDataURL(), wid, hit]
}
function selectMethod(event) {
let select = event.target
let keyInput = select.parentNode.querySelector('.key-input')
if (!keyInput.value) {
if (select.value == 'tomato') {
keyInput.value = defaultTomatoKey
} else {
keyInput.value = defaultOtherKey
}
}
if (select.value != 'tomato' && keyInput.value == defaultTomatoKey) {
keyInput.value = defaultOtherKey
}
if (select.value == 'tomato' && keyInput.value == defaultOtherKey) {
keyInput.value = defaultTomatoKey
}
}
function resizeImage(img) {
if (img.width < img.naturalWidth) {
img.height = img.naturalHeight * img.width / img.naturalWidth
} else if (img.height < img.naturalHeight) {
img.width = img.naturalWidth * img.height / img.naturalHeight
}
}
function pickImage(event) {
if (event.target.files.length <= 0) {
return
}
let container = event.target.parentNode
let img = isOriginalPicPage ? document.querySelector('.image_original_original') : container.nextSibling
if (!img) {
return
}
let url = URL.createObjectURL(event.target.files[0])
img.src = url
event.target.value = ''
if (!isOriginalPicPage) {
img.onload = ()=>resizeImage(img)
return
}
}
function encrypt(event) {
let container = event.target.parentNode
let img = isOriginalPicPage ? document.querySelector('.image_original_original') : container.nextSibling
if (!img) {
return
}
container.setAttribute('activated', 'true')
let select = container.querySelector('.method-select')
let msg = container.querySelector('.msg')
let key = container.querySelector('.key-input').value
if (!checkKeyValidity(select.value, key)) {
let msg
switch (select.value) {
case 'tomato':
msg = '小番茄算法仅支持大于0小于等于1.618的小数作为密钥'
break
case 'pe1': case 'pe2':
msg = 'PicEncrypt算法仅支持大于0小于1的小数作为密钥'
break
default:
msg = ''
break
}
alert(msg)
return
}
if (!first_config) {
first_config = {method: select.value, key: key}
document.querySelectorAll('.method-select').forEach(e=>{
let container = e.parentNode
if (container.getAttribute('activated') == 'true') {
return
}
e.value = select.value
let keyInput = container.querySelector('.key-input')
keyInput.value = key
})
}
let delay = 100
if (!img.crossOrigin) {
img.crossOrigin = 'anonymous'
}
img.style.display = 'none'
msg.style.display = ''
setTimeout(()=>{
console.time()
switch (select.value) {
case 'tomato':
encryptTomato(img, key)
break
case 'b':
img.src = encryptB2(img, key, 32, 32)[0]
break
case 'c2':
img.src = encryptC2(img, key)[0]
break
case 'c':
img.src = encryptC(img, key)[0]
break
case 'pe1':
img.src = encryptPE1(img, key)[0]
break
case 'pe2':
img.src = encryptPE2(img, key)[0]
break
}
console.timeEnd()
resizeImage(img)
img.style.display = 'inline-block'
msg.style.display = 'none'
}, delay)
}
function decrypt(event) {
let container = event.target.parentNode
let img = isOriginalPicPage ? document.querySelector('.image_original_original') : container.nextSibling
if (!img) {
return
}
container.setAttribute('activated', 'true')
let select = container.querySelector('.method-select')
let msg = container.querySelector('.msg')
let key = container.querySelector('.key-input').value
if (!checkKeyValidity(select.value, key)) {
let msg
switch (select.value) {
case 'tomato':
msg = '小番茄算法仅支持大于0小于等于1.618的小数作为密钥'
break
case 'pe1': case 'pe2':
msg = 'PicEncrypt算法仅支持大于0小于1的小数作为密钥'
break
default:
msg = ''
break
}
alert(msg)
return
}
if (!first_config) {
first_config = {method: select.value, key: key}
document.querySelectorAll('.method-select').forEach(e=>{
let container = e.parentNode
if (container.getAttribute('activated') == 'true') {
return
}
e.value = select.value
let keyInput = container.querySelector('.key-input')
keyInput.value = key
})
}
let delay = 100
if (!img.crossOrigin) {
img.crossOrigin = 'anonymous'
}
img.style.display = 'none'
msg.style.display = ''
setTimeout(()=>{
console.time()
switch (select.value) {
case 'tomato':
decryptTomato(img, key)
break
case 'b':
img.src = decryptB2(img, key, 32, 32)[0]
break
case 'c2':
img.src = decryptC2(img, key)[0]
break
case 'c':
img.src = decryptC(img, key)[0]
break
case 'pe1':
img.src = decryptPE1(img, key)[0]
break
case 'pe2':
img.src = decryptPE2(img, key)[0]
break
}
console.timeEnd()
resizeImage(img)
img.style.display = 'inline-block'
msg.style.display = 'none'
}, delay)
}
function restore(event) {
let container = event.target.parentNode
let img = isOriginalPicPage ? document.querySelector('.image_original_original') : container.nextSibling
if (!img) {
return
}
if (isOriginalPicPage) {
img.src = img.getAttribute('origin_url')
img.width = img.naturalWidth
img.height = img.naturalHeight
} else {
let id = img.getAttribute('pic_id')
img.src = pic_list[id].url
img.width = pic_list[id].width
img.height = pic_list[id].height
}
resizeImage(img)
}
function download(event) {
let container = event.target.parentNode
let img = isOriginalPicPage ? document.querySelector('.image_original_original') : container.nextSibling
if (!img) {
return
}
let image = new Image();
image.src = img.src;
image.setAttribute("crossOrigin", "anonymous");
image.onload = function() {
let a = document.createElement("a");
a.download = Date.now() + ".png"
if (img.src.startsWith('blob:') || img.src.startsWith('data:')) {
a.href = image.src
} else {
let canvas = document.createElement("canvas");
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
canvas.getContext("2d").drawImage(image, 0, 0, image.width, image.height);
a.href = canvas.toDataURL({format: 'png', quality: 1});
}
a.click();
}
}
// 添加用户界面
function addButton(img) {
let container = document.createElement('div')
container.className = 'pic-decrypt-container'
container.innerHTML = `
<select class="method-select">
<option value="tomato">🍅小番茄图片混淆</option>
<option value="b">方块混淆</option>
<option value="c2">行像素混淆</option>
<option value="c">逐像素混淆</option>
<option value="pe1">兼容PicEncrypt: 行模式</option>
<option value="pe2">兼容PicEncrypt: 行+列模式</option>
</select>
<input class="key-input" type="text" placeholder="输入密钥" value="${defaultTomatoKey}">
<br>
<input class="pick-image" type="file" accept="image/*" style="display:none;">
<input class="normal-btn pick-image-btn" type="button" value="选择图片" style="background-color: #28538F;color:#fff;">
<input class="normal-btn encrypt" type="button" value="混淆" style="background-color: #4f1787;color:#fff;">
<input class="normal-btn decrypt" type="button" value="解混淆" style="background-color: #eb3678;color:#fff;">
<input class="normal-btn restore" type="button" value="还原" style="background-color: #fb773c;color:#fff;">
<input class="normal-btn download" type="button" value="保存" style="background-color: #3385ff;color:#fff;">
<div class="scroll-img-btn">
<span class="pic-encrypt-arrow up"></span>
</div>
<div class="scroll-img-btn">
<span class="pic-encrypt-arrow down"></span>
</div>
<p class="msg" style="display: none;">正在处理图片...</p>
`
let styleHTML = `
<style>
.pic-decrypt-container {
margin-top: 0.5rem;
text-align: center;
}
.normal-btn, .method-select, .key-input, .pick-image {
float: center;
min-width: 5.2rem;
height: 3rem;
line-height: 3rem;
font-size: 1.6rem;
padding: 0 0.5rem;
margin: 0.5rem 0.6rem;
border-radius: 6px;
display: inline-block;
position: relative;
vertical-align: middle;
text-align: center;
}
.normal-btn {
border: 0;
}
.pick-image-btn {
width: 7rem;
}
.normal-btn:hover {
font-size: 1.7rem;
}
.method-select, .key-input {
border: 1px solid #888;
color: #000;
width: 200px;
}
.normal-btn:hover, .method-select:hover, .scroll-img-btn:hover {
cursor: pointer;
background-color: #ddd;
}
.key-input:hover {
cursor: text;
}
.scroll-img-btn {
margin-top: 0.5rem;
margin-left: 0.6rem;
border: 1px solid rgb(153, 153, 153);
border-radius: 6px;
display: inline-block;
width: 28px;
height: 28px;
}
.pic-encrypt-arrow {
position: relative;
border-width: 0px 3px 3px 0px;
border-style: solid;
border-color: rgb(136, 136, 136);
display: inline-block;
padding: 3px;
}
.up {
top: 4px;
transform: rotate(-135deg);
}
.down {
top: 0px;
transform: rotate(45deg);
}
.msg {
margin: 1.5rem;
color: ${isOriginalPicPage ? '#fff' : '#000'};
font-size: 2.5rem;
}
</style>
`
document.querySelector('head').innerHTML += styleHTML
if (isOriginalPicPage) {
let div = document.querySelector('.af_reply_container #af_reply_editor')
if (!div) {
return
}
div.parentNode.insertBefore(container, div)
} else {
let pic_id = img.getAttribute('pic_id')
img.src = pic_list[pic_id].url
img.parentNode.insertBefore(container, img)
}
if (first_config) {
container.querySelector('select').value = first_config.method
let keyInput = container.querySelector('.key-input')
keyInput.value = first_config.key
}
let pickImageInput = container.querySelector('.pick-image')
container.querySelector('.pick-image-btn').onclick = ()=>pickImageInput.click()
container.querySelector('.pick-image').onchange = pickImage
container.querySelector('select').onchange = selectMethod
container.querySelector('.encrypt').onclick = encrypt
container.querySelector('.decrypt').onclick = decrypt
container.querySelector('.restore').onclick = restore
container.querySelector('.download').onclick = download
container.querySelector('.up').parentElement.onclick = ()=>scrollToNextImage(true)
container.querySelector('.down').parentElement.onclick = ()=>scrollToNextImage(false)
}
// 获取某个帖子中某一页的所有原图链接
function loadPicList(tid) {
let kw = (document.querySelector('.card_head a') || location).href.match(/kw=[%\w]+&/g)
if (kw == null) {
return
}
kw = kw[0].substring(3, kw[0].length-1)
document.querySelectorAll('.BDE_Image').forEach(img=>{
if (img.previousElementSibling && img.previousElementSibling.classList.contains('pic-decrypt-container')) {
return
}
let pic_id = img.src.match(/\/[a-f0-9]*\.jpg/g)
if (pic_id == null) {
return
}
pic_id = pic_id[0].substring(1, pic_id[0].length-4)
img.setAttribute('pic_id', pic_id)
let guideUrl = `https://tieba.baidu.com/photo/bw/picture/guide?kw=${kw}&tid=${tid}&alt=jview&see_lz=0&pic_id=${pic_id}`
let xhr = new XMLHttpRequest()
xhr.open('GET', guideUrl, true)
xhr.onreadystatechange = ()=>{
if (xhr.readyState != 4 || xhr.status != 200) {
return
}
let response = JSON.parse(xhr.response)
Object.values(response.data.pic_list).forEach(imgSrc=>{
let original = imgSrc.img.original
pic_list[original.id] = {'url': original.url || original.waterurl, 'width': original.width, 'height': original.height}
})
guideUrl = `https://tieba.baidu.com/photo/bw/picture/guide?kw=${kw}&tid=${tid}&alt=jview&see_lz=1&pic_id=${pic_id}`
xhr.open('GET', guideUrl, true)
xhr.onreadystatechange = ()=>{
if (xhr.readyState != 4 || xhr.status != 200) {
return
}
let response = JSON.parse(xhr.response)
Object.values(response.data.pic_list).forEach(imgSrc=>{
let original = imgSrc.img.original
pic_list[original.id] = {'url': original.url || original.waterurl, 'width': original.width, 'height': original.height}
})
if (!img.previousElementSibling || !img.previousElementSibling.classList.contains('pic-decrypt-container')) {
addButton(img)
}
}
xhr.send()
}
xhr.send()
})
}
// 获取元素上缘到页面顶端的距离
function getElementTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current !== null){
actualTop += current. offsetTop;
current = current.offsetParent;
}
return actualTop;
}
// 获取距离浏览器可视区垂直中点最近的图片
function getCenterImg() {
let minDelta = 100000000
let centerImg = null
let viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
let centerScrollTop = document.documentElement.scrollTop + viewPortHeight / 2
let images = document.querySelectorAll('.BDE_Image')
for (let i = 0; i < images.length; ++i) {
let img = images[i]
let top
let bottom
if (img.parentElement.classList.contains('replace_div')) {
top = getElementTop(img.parentElement)
bottom = top + img.parentElement.clientHeight
} else {
top = getElementTop(img)
bottom = top + img.height
}
let delta = Math.abs((top + bottom)/2 - centerScrollTop)
if (delta < minDelta) {
centerImg = img
minDelta = delta
} else {
break
}
}
return centerImg
}
// 获取距离浏览器可视区域垂直中点最近且位于可视区内的图片
function getFocusImg() {
let viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
let centerScrollTop = document.documentElement.scrollTop + viewPortHeight / 2
let images = document.querySelectorAll('.BDE_Image')
for (let i = 0; i < images.length; ++i) {
let img = images[i]
let top
let bottom
if (img.parentElement.classList.contains('replace_div')) {
top = getElementTop(img.parentElement)
bottom = top + img.parentElement.clientHeight
} else {
top = getElementTop(img)
bottom = top + img.height
}
if (centerScrollTop < top && document.documentElement.scrollTop + viewPortHeight > top) {
return img
} else if (top > document.documentElement.scrollTop + viewPortHeight || bottom < document.documentElement.scrollTop) {
continue
} else if (centerScrollTop >= top && centerScrollTop <= bottom) {
return img
} else if (i < images.length - 1) {
return centerScrollTop - bottom <= getElementTop(images[i+1].parentElement) - centerScrollTop ? img : images[i+1]
} else if (bottom > document.documentElement.scrollTop) {
return img
}
}
return null
}
function checkKeyValidity(method, key) {
switch (method) {
case 'tomato':
try {
return parseFloat(key) > 0 && parseFloat(key) <= 1.618
} catch (e) {
return false
}
case 'pe1': case 'pe2':
try {
return parseFloat(key) > 0 && parseFloat(key) < 1
} catch (e) {
return false
}
default:
return true
}
}
function scrollToNextImage(isReverse) {
if (isOriginalPicPage) {
document.querySelector(isReverse ? '.image_original_prev' : '.image_original_next').click()
} else {
let images = document.querySelectorAll('.BDE_Image')
let centerImg = getCenterImg()
for (let i = 0; i < images.length; ++i) {
if (!images[i].isEqualNode(centerImg)) {
continue
}
let scroll
if (isReverse) {
if (i > 0) {
scroll = getElementTop(images[i-1].previousElementSibling)
} else {
scroll = getElementTop(centerImg.previousElementSibling)
}
} else {
let top = getElementTop(centerImg.previousElementSibling)
if (Math.abs(top - 60 - document.documentElement.scrollTop) > 50) {
scroll = top
} else if (i < images.length - 1) {
scroll = getElementTop(images[i+1].previousElementSibling)
} else {
scroll = getElementTop(centerImg.previousElementSibling)
}
}
if (scroll > 60) {
scroll -= 60
}
document.documentElement.scrollTo({top: scroll, behavior: 'smooth'})
break
}
}
}
function removeLoginBox() {
let login = document.getElementById('tiebaCustomPassLogin')
if (login) {
login.remove()
return true
}
return false
}
function main() {
if (!removeLoginBox()) {
setTimeout(removeLoginBox, 500)
}
function onChangedPage() {
setTimeout(()=>document.querySelectorAll('.l_posts_num a, .l_posts_num span, .l_posts_num button').forEach(e=>e.onclick = ()=>{
setTimeout(()=>{
removeLoginBox()
onChangedPage()
}, 500)
}), 500)
}
onChangedPage()
let tid = location.href.match(/tieba\.baidu\.com\/p\/\d+/g)
isOriginalPicPage = false
if (tid == null) {
if (location.href.match(/tieba\.baidu\.com\/photo\/p\?/g) == null) {
return
} else {
tid = new URLSearchParams(location.href.split('?')[1]).get('tid')
if (tid == null) {
return
}
}
isOriginalPicPage = true
} else {
tid = tid[0].substr(18)
}
// 查看原图的页面
if (isOriginalPicPage) {
let id = setInterval(()=>{
let img = document.querySelector('.image_original_original')
let div = document.querySelector('.af_reply_container #af_reply_editor')
if (!img || !div) {
return
}
clearInterval(id)
addButton(img)
function onImageChanged() {
setTimeout(()=>{
let img = document.querySelector('.image_original_original')
if (!img.src.startsWith('blob:') && !img.src.startsWith('data:')) {
img.setAttribute('origin_url', img.src)
}
}, 80)
}
window.onclick = onImageChanged
img.parentNode.onmousewheel = onImageChanged
setInterval(()=>{
let img = document.querySelector('.image_original_original')
if (!img || img.classList.contains('ui-draggable')) {
return
}
if (Math.abs(img.width / img.naturalWidth - img.height / img.naturalHeight) < 0.05 && Math.abs(img.width - img.naturalWidth) / img.naturalWidth < 0.05) {
return
}
let width = img.naturalWidth
let height = img.naturalHeight
let imgParent = img.parentNode
if (width > imgParent.clientWidth) {
width = imgParent.clientWidth
height = height * width / img.naturalWidth
}
if (height > imgParent.clientHeight) {
width = width * imgParent.clientHeight / height
height = imgParent.clientHeight
}
img.style.width = width + 'px'
img.style.height = height + 'px'
img.style.left = (imgParent.clientWidth - width) / 2 + 'px'
img.style.top = (imgParent.clientHeight - height) / 2 + 'px'
}, 1000)
}, 500)
} else { // 具体某个帖子的页面
loadPicList(tid)
setInterval(()=>{
loadPicList(tid)
}, 2000)
}
// 添加快捷键
// 切换混淆方法(Method) M
// 反向切换混淆方法 Shift + M
// 输入密钥(Key) K
// 确定密钥 Enter
// 选择图片(Pick image) P
// 混淆(Encrypt) E
// 解混淆(Decrypt) D
// 还原(Restore) R
// 保存(Save) S
window.onkeypress = (event)=>{
let container
if (isOriginalPicPage) {
if (event.code == 'ArrowLeft' || event.code == 'ArrowRight') {
onImageChanged()
}
if (document.activeElement.classList.contains('j_ed_container') || document.activeElement.classList.contains('.key-input')) {
return
}
container = document.querySelector('.pic-decrypt-container')
} else {
if (event.target.id == 'j_editor_for_container' || event.target.id == 'ueditor_replace' || event.target.classList.contains('j_search_input')) {
return
}
let focusImg = getFocusImg()
if (!focusImg && event.code != 'KeyN') {
return
}
let centerImg = getCenterImg()
if (!centerImg || centerImg.previousElementSibling && !centerImg.previousElementSibling.classList.contains('pic-decrypt-container')) {
return
}
container = centerImg.previousElementSibling
}
let select = container.querySelector('.method-select')
let options = select.children
switch (event.code) {
case 'KeyM':
for (let i = 0; i < options.length; ++i) {
if (options[event.shiftKey ? options.length-i-1 : i].value == select.value) {
select.value = options[event.shiftKey ? options.length-(i+1)%options.length-1 : (i+1)%options.length].value
let keyInput = container.querySelector('.key-input')
if (select.value == 'tomato') {
keyInput.value = defaultTomatoKey
} else {
keyInput.value = defaultOtherKey
}
break
}
}
break
case 'KeyD':
container.querySelector('.decrypt').click()
break
case 'KeyE':
container.querySelector('.encrypt').click()
break
case 'KeyR':
container.querySelector('.restore').click()
break
case 'KeyP':
container.querySelector('.pick-image').click()
break
case 'KeyS':
container.querySelector('.download').click()
break
case 'KeyK':
setTimeout(()=>container.querySelector('.key-input').focus(), 100)
break
case 'Enter': case 'NumpadEnter':
container.querySelector('.key-input').blur()
break
case 'KeyN':
scrollToNextImage(event.shiftKey)
break
}
}
}
main()