右侧可展开/收起的侧边栏组件

在网页右侧显示一个可展开/收起的侧边栏组件,包含加密和解密功能。

当前为 2025-01-18 提交的版本,查看 最新版本

// ==UserScript==
// @name         右侧可展开/收起的侧边栏组件
// @namespace    https://bgm.tv
// @version      0.16
// @description  在网页右侧显示一个可展开/收起的侧边栏组件,包含加密和解密功能。
// @author       Rin
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    let table;

function initGbkTable() {
  // https://en.wikipedia.org/wiki/GBK_(character_encoding)#Encoding
  const ranges = [
    [0xA1, 0xA9,  0xA1, 0xFE],
    [0xB0, 0xF7,  0xA1, 0xFE],
    [0x81, 0xA0,  0x40, 0xFE],
    [0xAA, 0xFE,  0x40, 0xA0],
    [0xA8, 0xA9,  0x40, 0xA0],
    [0xAA, 0xAF,  0xA1, 0xFE],
    [0xF8, 0xFE,  0xA1, 0xFE],
    [0xA1, 0xA7,  0x40, 0xA0],
  ]
  const codes = new Uint16Array(23940)
  let i = 0

  for (const [b1Begin, b1End, b2Begin, b2End] of ranges) {
    for (let b2 = b2Begin; b2 <= b2End; b2++) {
      if (b2 !== 0x7F) {
        for (let b1 = b1Begin; b1 <= b1End; b1++) {
          codes[i++] = b2 << 8 | b1
        }
      }
    }
  }
  table = new Uint16Array(65536)
  table.fill(0xFFFF)

  const str = new TextDecoder('gbk').decode(codes)
  for (let i = 0; i < str.length; i++) {
    table[str.charCodeAt(i)] = codes[i]
  }
}
const NodeJsBufAlloc = typeof Buffer === 'function' && Buffer.allocUnsafe

const defaultOnAlloc = NodeJsBufAlloc
  ? (len) => NodeJsBufAlloc(len)
  : (len) => new Uint8Array(len)

const defaultOnError = () => 63   // '?'


window.encodeToGBK = function(str, opt = {}) {
  if (!table) {
    initGbkTable()
  }
  const onAlloc = opt.onAlloc || defaultOnAlloc
  const onError = opt.onError || defaultOnError

  const buf = onAlloc(str.length * 2)
  let n = 0

  for (let i = 0; i < str.length; i++) {
    const code = str.charCodeAt(i)
    if (code < 0x80) {
      buf[n++] = code
      continue
    }
    const gbk = table[code]

    if (gbk !== 0xFFFF) {
      buf[n++] = gbk
      buf[n++] = gbk >> 8
    } else if (code === 8364) {
      // 8364 == '€'.charCodeAt(0)
      // Code Page 936 has a single-byte euro sign at 0x80
      buf[n++] = 0x80
    } else {
      const ret = onError(i, str)
      if (ret === -1) {
        break
      }
      if (ret > 0xFF) {
        buf[n++] = ret
        buf[n++] = ret >> 8
      } else {
        buf[n++] = ret
      }
    }
  }
  return buf.subarray(0, n)
}
console.log(window.encodeToGBK("我操sai怎么这么坏啊"));
    // 创建侧边栏容器
    const sidebar = document.createElement('div');
    sidebar.id = 'custom-sidebar';
    sidebar.style.position = 'fixed';
    sidebar.style.top = '50%';
    sidebar.style.right = '-200px'; // 初始隐藏位置
    sidebar.style.transform = 'translateY(-50%)';
    sidebar.style.width = '200px';
    sidebar.style.height = 'auto';
    sidebar.style.backgroundColor = '#333';
    sidebar.style.color = '#fff';
    sidebar.style.padding = '20px';
    sidebar.style.boxShadow = '-2px 0 5px rgba(0,0,0,0.5)';
    sidebar.style.transition = 'right 0.3s ease-in-out';
    sidebar.style.zIndex = '9999';

    // 添加点击事件监听器以切换侧边栏状态
    let isSidebarOpen = false;
    sidebar.addEventListener('click', (event) => {
        if (!isSidebarOpen) {
            sidebar.style.right = '0';
        } else {
            sidebar.style.right = '-200px';
        }
        isSidebarOpen = !isSidebarOpen;
    });

    // 创建面板内容
    const panel = document.createElement('div');
    panel.style.textAlign = 'center';

    const inputField = document.createElement('input');
    inputField.type = 'text';
    inputField.placeholder = '输入数据';
    inputField.style.width = '160px';
    inputField.style.height = '30px';
    inputField.style.marginBottom = '10px';
    inputField.style.padding = '5px';
    inputField.style.border = '1px solid #555';
    inputField.style.backgroundColor = '#444';
    inputField.style.color = '#fff';
    inputField.addEventListener('click', (event) => {
        event.stopPropagation(); // 阻止事件冒泡
    });

    const encryptButton = document.createElement('button');
    encryptButton.textContent = '加密';
    encryptButton.style.width = '75px';
    encryptButton.style.height = '30px';
    encryptButton.style.marginRight = '10px';
    encryptButton.style.cursor = 'pointer';
    encryptButton.style.border = 'none';
    encryptButton.style.backgroundColor = '#555';
    encryptButton.style.color = '#fff';
    encryptButton.addEventListener('click', (event) => {
        event.stopPropagation(); // 阻止事件冒泡
        const encryptedData = encrypt(inputField.value);
        inputField.value = encryptedData;
    });

    const decryptButton = document.createElement('button');
    decryptButton.textContent = '解密';
    decryptButton.style.width = '75px';
    decryptButton.style.height = '30px';
    decryptButton.style.cursor = 'pointer';
    decryptButton.style.border = 'none';
    decryptButton.style.backgroundColor = '#555';
    decryptButton.style.color = '#fff';
    decryptButton.addEventListener('click', (event) => {
        event.stopPropagation(); // 阻止事件冒泡
        const decryptedData = decrypt(inputField.value);
        inputField.value = decryptedData;
    });

    panel.appendChild(inputField);
    panel.appendChild(encryptButton);
    panel.appendChild(decryptButton);

    sidebar.appendChild(panel);

    // 将侧边栏添加到body中
    document.body.appendChild(sidebar);

    // 假设已经实现了加密和解密方法
    function encrypt(data) {
        // 这里应该是实际的加密逻辑
        const str = "你好,世界!";

// 将字符串转换为 GBK 编码的二进制数据(Buffer)
const gbkBuffer = iconv.encode(str, 'gbk');

console.log(gbkBuffer);
        return data; // 返回示例
    }

    function decrypt(data) {
        // 这里应该是实际的解密逻辑
        return data; // 返回示例
    }
})();