sync.lua
按下 Shift+F9 时将选中内容复制后同步到服务端。Shift+F8 时将服务端的内容粘贴到光标位置。
如果你没有服务器,可以试试这个文本存储服务:textdb.dev。
加解密方法 crypt() 见 AES-256-CBC PKCS7 SHA256 SALT PBKDF2 中 Hammerspoon 部分。
-- 远程剪贴板 hs.hotkey.bind( {'shift'}, 'f9', function() hs.eventtap.keyStroke({ "cmd" }, "c") local text = hs.pasteboard.readString() local encrypted = crypt(text, password) if encrypted then text = encrypted end local url = 'https://upall.cn/pasteboard/' local headers = { ['Content-Type'] = 'text/plain', } local code, body, headers = hs.http.post(url, text, headers) hs.alert.show("Pasteboard:" .. body) end ) hs.hotkey.bind( {'shift'}, 'f8', function() local url = 'https://upall.cn/pasteboard/' local code, body, headers = hs.http.get(url) local decrypted = crypt(body, password, false) if decrypted then body = decrypted end hs.pasteboard.setContents(body) hs.eventtap.keyStroke({ "cmd" }, "v") end )
server
第一版
注:未根据操作系统自动转编码,只能支持纯 ASCII 字符,跨平台粘贴 unicode 字符可能不正常(操作系统默认编码不同的原因,GBK/UTF-8)。Windows 粘贴 macOS 的中文可能会乱码;macOS/Linux 粘贴 Windows 可能会因乱码而无法粘贴。
error_reporting(0); $method = $_SERVER['REQUEST_METHOD']; if ($method == 'POST') { $data = file_get_contents("php://input"); $data or exit(); #file_put_contents('./plain.txt', "\n\n>>>>" . date('Y-m-d H:i:s') . "\n", FILE_APPEND); #$r = file_put_contents('./plain.txt', $data, FILE_APPEND); $r = file_put_contents('./plain.txt', $data); echo $r; } else if ($method == 'GET') { header('content-type: text/plain; charset=utf-8'); echo file_get_contents('./plain.txt'); } else { exit("unknown mehtod: $method"); }
第二版
注:根据操作系统自动转编码,转码需要先解密再加密需要额外占用响应时间。已加入中文检测,纯英文时不会走转码流程。
依赖:aes.inc.php
error_reporting(0); include('./aes.inc.php'); // 详见 https://blog.upall.cn/509.html 中 PHP 部分 $method = $_SERVER['REQUEST_METHOD']; $password = 'xxxxxxxxxxxxxxxxxx'; // 密钥(必须是16、24或32字节,对应AES-128、AES-192或AES-256) $platform = 'other'; $userAgent = $_SERVER['HTTP_USER_AGENT']; if ($userAgent) { if (preg_match('/Win32|Win64/i', $userAgent)) { $platform = 'windows'; } elseif (preg_match('/Hammerspoon/i', $userAgent) || preg_match('/Darwin/i', $userAgent) || preg_match('/Mac OS/i', $userAgent)) { $platform = 'macos'; } } if ($method == 'POST') { $input = file_get_contents("php://input"); $input or exit(); $decrypted = decrypt($input, $password); // 包含ASCII以外字符时存储来源平台以在读取时转换编码(macos不能往pasteboard写乱码) if (preg_match('/[^\x00-\x7F]/', $decrypted) === 1) { $platformEncrypted = encrypt($platform, $password); $content = "$input.$platformEncrypted"; } else { $content = $input; } $r = file_put_contents('./plain.txt', $content); $plainLen = mb_strlen($decrypted); echo "$plainLen/$r"; } else if ($method == 'GET') { $data = file_get_contents('./plain.txt') ?: ''; if ($data && mb_strpos($data, '.') === false) { header('content-type: text/plain; charset=utf-8'); echo $data; } else { [$crypted, $platformEncrypted] = explode('.', $data); $fromPlatform = decrypt($platformEncrypted, $password); // 如果写平台与读平台相同则直接返回 if ($fromPlatform == $platform) { header('content-type: text/plain; charset=utf-8'); echo $crypted; } // 转换为对应OS的编码 else { $fromEncoding = $fromPlatform == 'windows' ? 'GBK' : 'UTF-8'; $toEncoding = $platform == 'windows' ? 'GBK' : 'UTF-8'; header("content-type: text/plain; charset=$toEncoding"); if ($fromEncoding != $toEncoding) { $decrypted = decrypt($crypted, $password); $decrypted = mb_convert_encoding($decrypted, $toEncoding, $fromEncoding); $crypted = encrypt($decrypted, $password); } echo $crypted; } } } else { exit("unknown mehtod: $method"); }
注:移除加解密功能可以显著减小响应时间。