Spiritの小站 https://spiritx.xyz Mon, 02 Mar 2020 03:49:06 +0000 zh-CN hourly 1 使用VirtualBox启动本地硬盘上的Win 10系统 https://spiritx.xyz/1037.html https://spiritx.xyz/1037.html#comments Sun, 01 Mar 2020 15:49:58 +0000 https://spiritx.xyz/?p=1037
从 Arch Linux 启动 Windows 10分区]]>

前言

了更好的性能,当初装系统时选择了双系统的方式,又为了满足我对于几款win平台软件的需求,安装了一台 Win 7 虚拟机(前不久换成了 Win 8.1)。近来发现,Windows 10虽然作为我的必备系统,但我打开她的频率不是太高,而且Windows虚拟机由于需求越来越多,磁盘剩余逐渐变小。于是我想到把我“闲置”的Win 10系统利用起来,一方面,经过我几年的使用和配置,肯定比虚拟机用得顺手,同时也免去了开机切换系统的麻烦;另一方面,当初装系统时给 Win 10 分配的空间比Arch Linux多很多,如果利用起来的话,我Arch上的一些替代软件就可以删除了,这样可以给我腾出不少空间。
PS: 本文所用的这种方式启动的Windows肯定是存在问题的,最明显的就是驱动的问题了,建议三思后再尝试!

从 Arch Linux 启动 Windows 10

查看分区情况

首先,看看我的分区情况

 ~  sudo fdisk -l
...
设备                起点      末尾      扇区   大小 类型
/dev/nvme0n1p1      2048    206847    204800   100M EFI 系统
/dev/nvme0n1p2    206848    468991    262144   128M Microsoft 保留
/dev/nvme0n1p3    468992 395255172 394786181 188.3G Microsoft 基本数据
/dev/nvme0n1p4 395257856 500118158 104860303    50G Linux 文件系统
/dev/sda1  *     2048 488394751 488392704 232.9G  7 HPFS/NTFS/exFAT
...

前3个就是我所需的的分区了,其中我电脑的Win 10系统就在/dev/nvme0n1p3分区

获取读写分区的权限

为了避免使用 root 运行 VirtualBox,所以需要给自己访问磁盘的权限,因为我的Win 10使用UEFI 启动,所以 UEFI 分区的权限也是需要的

## 为当前用户获取硬盘分区读写权限
 ~  sudo setfacl -m u:${USER}:rw /dev/nvme0n1p{1,2,3}
## 为当前用户获取硬盘读写权限
 ~  sudo setfacl -m "u:${USER}:rw" /dev/nvme0n1

创建 VirtualBox 的硬盘映射文件

创建之前需要先获取整块硬盘的读写权限,要注意的是nvme SSD的设备名称是nvme0n1

## 创建磁盘映射文件 windows.vmdk
 ~  VBoxManage internalcommands createrawvmdk -filename windows.vmdk -rawdisk /dev/nvme0n1 -partitions 1,2,3 -relative
## 创建完成后可以撤销对 nvme0n1 的权限
 ~  sudo setfacl -b /dev/nvme0n1

使用-partitions 1,2,3选项的话,只有这三个分区能在虚拟机里访问,别的分区读的时候是全零,写入操作会被忽略。-relative选择使用分区设备名(nvme0n1p1、nvme0n1p2、nvme0n1p3),这样创建好之后 VirtualBox 不再需要对整块硬盘 nvme0n1 的权限了。另外会附带创建一个名字以 -pt.vmdk 结尾的文件。它是单独的分区表。

配置bios dmi(可选

这一步主要是为了配置一些主板额外的信息,参考Configuring the BIOS DMI Information。注意:如果你和我一样是使用UEFI启动的话,代码语句里面的pcbios应换为efi。示例如下:

## 可能需要
 ~  sudo pacman -S dmidecode
## 获取dmi type0的信息
 ~  sudo dmidecode -t0
## Windows 10 即为虚拟机名字,10/23/2018就在刚获取的dmi信息中
 ~  VBoxManage setextradata "Windows 10" "VBoxInternal/Devices/efi/0/Config/DmiBIOSReleaseDate" "10/23/2018" 

使用虚拟机

打开 VirtualBox,按照常规步骤创建虚拟机,硬盘就选刚创建的磁盘映射文件,创建完成后记得在设置-系统-主板里勾选 启用EFI,然后就可以开机了。注意:重启后必须重新为当前用户获取硬盘分区读写权限!sudo setfacl -m u:${USER}:rw /dev/nvme0n1p{1,2,3}
话不多说,先上图


美中不足的是打开发现数字许可证失效了orz,而且指纹和pin解锁不能使用,经过一番Google,应该是TPM失效的缘故,而 VirtualBox 不支持vTPM......看来我只能将就用了。值得一提的是,如果你是通过主板硬件来激活 Windows 的话,那么可以尝试下下面这个方法(虽然我也没试过,不过理论上来讲没问题~~ :流汗滑稽:

## 查看key
 ~  sudo cat /sys/firmware/acpi/tables/MSDM
## 如果没有的话就放弃吧~_~
## 把key导出
 ~  sudo dd if=/sys/firmware/acpi/tables/MSDM of=/home/spirit/VirtualBox VMs/msdm.bin
## 导入虚拟机
 ~  VBoxManage setextradata "Windows 10" "VBoxInternal/Devices/acpi/0/Config/CustomTable" "/home/spirit/VirtualBox VMs/msdm.bin"

后记

既然可以从Linux启动Win,那能不能从Win启动Linux呢,我试着创建了一个磁盘映射,答案是可以的,不过需要注意的是操作均需在管理员权限下执行。Win+x,点击磁盘管理,查看硬盘序号,我的系统盘是磁盘1,所以硬盘选择了\\.\PhysicalDrive1

## 列出磁盘分区
C:\Users\spirit\Documents> "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" internalcommands listpartitions -rawdisk "\\.\PhysicalDrive1"
Number  Type   StartCHS       EndCHS      Size (MiB)  Start (Sect)
1       0x00  0   /0  /0   0   /0  /0            100         2048
2       0x00  0   /0  /0   0   /0  /0            128       206848
3       0x00  0   /0  /0   0   /0  /0         192766       468992
4       0x00  0   /0  /0   0   /0  /0          51201    395257856
## 创建磁盘映射linux.vmdk
C:\Users\spirit\Documents> "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" internalcommands createrawvmdk -filename linux.vmdk -rawdisk "\\.\PhysicalDrive1" -partitions 1,4

之后和前面一样,创建虚拟机,注册虚拟磁盘,不过需要注意的是以管理员身份运行 VirtualBox

参考文章:

]]>
https://spiritx.xyz/1037.html/feed/ 2
我为什么不将微信作为常用软件 https://spiritx.xyz/1031.html https://spiritx.xyz/1031.html#comments Fri, 06 Dec 2019 14:10:48 +0000
“加个微信吧!” “抱歉,我用QQ。”]]>

只一次遇到别人惊讶:“你居然没用微信!” 作为一名学生,虽然我对QQ的一些方面也不大满意,但我觉得QQ已经满足我所有的需求了,我非常不想在我的手机上安装两个功能重叠的app,但碍于一些原因,我也不得不在手机上安装一个微信,但每次打开微信时各种订阅号、公众号推送让我很是心烦。屏蔽吧怕错过一些重要消息,不屏蔽吧待处理消息分分钟99+。我的家长亲戚中很多人都用微信,在得知我居然在用QQ,他们都会诧异道:“什么年代了,你居然还在用QQ!” 也许我就是那个落后于潮流前沿的人吧 :doge笑哭: :doge笑哭:

我常用的IM和IRC软件为:QQ > Telegram > yaaic/HexChat > 微信。QQ的功能十分完善,但也有不少臃肿的东西,比如会员,Q钻什么的,这点不如微信;至于Telegram,就不用多说,详见这篇文章这篇文章;相较于IM软件,IRC软件就比较简陋,但作为聊天来使用却是十分合适,没有太多无用信息刷屏,操作方式带有极客范儿,不过由于年代久远,服务器数目已经大不如前,目前我主要在freenode的服务器上。微信的话,我将在接下来提到。

理念
在微信之前的时代,网民们的网络身份通常是电子邮件地址。而微信的出现,改变了这一点:把手机号以做成了第一身份认证手段。把手机号做成了凌驾于身份证之上的认证手段。这与一些要求手机号绑定但手机号并非第一认证手段的app,是不相同的。我第一个微信号时在初中时创建的,当时的注册方式是一张未实名的移动卡,在手机掉了之后,那个微信号就随之消失了,也不知道被谁注册到了那个手机号,然后再通过手机号登上了我的微信 :捂脸: 。虽然我非常不喜欢这种通过手机号认证的方式,奈何有几个常用的App无法舍弃,只得老老实实去用手机号注册。现在用的微信号是我初二的时候通过关联QQ号注册得到的,那时候的微信有个很方便的功能:收发QQ消息。为了尝鲜,我使用了一段时间,然而有一天,点击接收的QQ消息后,它却告诉我不再支持此功能了(???黑人问号脸),把QQ用户骗到这里来,然后就不管了??
啥也干不了的PC端
使用过PC端微信的人,都会遇到一个蛋疼的问题:扫码登录。不知道微信的策划是怎么想的,难道怕用户记不住密码吗 :doge笑哭: ,之后还有“密码不如扫码安全”的逻辑,对此,我敢苟同。只能说各有各的好处,但并没有直接证据可证明扫码比密码安全,只能说这是一个很蛋疼的设计。受此荼毒,企业邮箱现在也是扫码登录,所以,我选择迁移到了Yandex。此外,微信的PC端功能很少,许多操作只能在手机上完成,就连红包功能也是最近才加入PC端的。
辣鸡的相册
微信的Android端在选取图片时,并没有调用系统相册,反而是自己造了个轮子,关键是还不如系统自带的相册好用,反而多出来一大堆预览图缓存,占用手机的存储空间
备份麻烦的聊天记录
腾讯微信官方一直不提供导出聊天记录到CSV或TXT文件的功能,用户的数据安全无法得到保障。即使其表明用户聊天数据点对点加密服务器不留底不储存,所以聊天记录只能保存在双方设备上,然而由于聊到敏感话题被封禁甚至被拘留这种新闻屡屡可见,那么问题来了,证据是从哪收集到的 :喷2: 我想说:既然立了牌坊就别去当**
不成熟的群聊
QQ群在功能上碾压微信群聊——发公告发通知,永久保存群文件,传文档,下表格,共享资源,回复功能,压缩包,管理员组织能力,碾压微信。更别说QQ还自带邮箱和网盘了。 至于QQ空间的日志相册评论转发等多媒体功能更是碾压微信朋友圈。
烂大街的公众号
开通公众号门槛极低,所以导致了一大堆辣鸡公众号天天发一些震惊、养生、鸡汤,也不管信息可信,只管发,为了引入流量,真什么都敢写...如果你加了长辈群,那么群里一定充斥着震惊养生造谣鸡汤等等,我本人特讨厌鸡汤还有那种没什么质量的短视频,长辈们居然觉得很不错。

以上所述即为我不用微信的几个理由,但世事无绝对,我只能说在现在的情况,因为谁也不能保证未来一切尽在掌握,也许有一天微信填补了它所有的缺陷,也许有一天我因为特殊原因不得不24小时开着微信...... :傲慢:

近年来移动端发展迅速,社交软件中微信可以说是首当其冲了(简陋的电脑端、必须扫码、文件大小限制等),似乎微信设计之初就没有将PC端作为其主要战场,而是将这片土地留给了它的兄弟QQ,但是它在移动端领域却是有取代QQ之势,反观手机QQ却一直没有碰微信的市场的意思,虽然推出了办公使用的Tim(一年没更新了),但没有触及到微信的核心利益,QQ、微信各有不可替代的作用和定位,作为同一家公司的软件,我想,如果要将功能都做得相同在技术上很容易实现,但这样结果必定不会好。毕竟,利益最大化才是问题关键。

]]>
https://spiritx.xyz/1031.html/feed/ 18
Posting file via wp_remote_post https://spiritx.xyz/1029.html https://spiritx.xyz/1029.html#comments Tue, 26 Nov 2019 08:47:41 +0000 https://spiritx.xyz/1029.html send an HTTP POST request using wp built-in function]]>

For several reasons I don't want to use curl, and I have known that WordPress has methods for HTTP request, so I choose wp_remote_post(), which allows you to send an HTTP post request, and return an array. Here's the code example:

<?php
$upload_url = "URL_YOUR_UPLOAD_FILE_TO";
$local_file = "PATH/TO/FILE";
$filename = basename($local_file);
$name = $local_file;  //name of Form Control
$Boundary = wp_generate_password();  //split signal, see: https://www.ietf.org/rfc/rfc1867.txt
$bits = file_get_contents($local_file);

$args = array(
    "headers" => "Content-Type: multipart/form-data; boundary=$Boundary\r\n\r\nAuthorization: Basic $client_id\r\n\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97",
    "body" => "--$Boundary\r\nContent-Disposition: form-data; name=\"$name\"; filename=\"$filename\"\r\n\r\n$bits\r\n\r\n--$Boundary--"
);

$response = wp_remote_post($upload_url, $args);
if (!is_wp_error($response)) {
    $reply = $response["body"];  //the remote server's reply
    var_dump($reply);
}
?>

reference: https://www.jianshu.com/p/29e38bcc8a1d

]]>
https://spiritx.xyz/1029.html/feed/ 4
WordPress评论支持Markdown https://spiritx.xyz/1026.html https://spiritx.xyz/1026.html#comments Sun, 17 Nov 2019 12:09:22 +0000 https://spiritx.xyz/?p=1026
WordPress评论免插件支持Markdown]]>

缘由

之前有过一篇记一次小站评论功能的修改,目的是为了防止xss攻击,当时我使用的评论 Markdown 解析器是 WP-Editor.md 插件,最近更新WP发现插件有冲突,遂禁用了它,换用代码实现,如果你和我一样使用的是同一款主题的话,commit 已提交,快去更新吧~

引入Markdown解析器

原理很简单,与 WP-Editor.md 类似,在评论提交时,首先检查评论的合法性,再将评论转换为 HTML 并写入数据库,同时,原 Markdown 评论也储存进数据库,为了这样,我在 wp_comments 里增加了一个字段 comment_markdown,在读取评论打印的时候,直接显示转换好的html,这样做有个好处就是不用每次都转换评论,节省了不少资源,同时,原格式的评论有一个存档,虽然增加了数据库的一点点体积,但我认为不错。
用到了下面这个程序

这里下载源码,我们所需要的是压缩包里面的 Parsedown.php ,将它放入主题目录的任一位置
functions.php 里面引入它:

...
include path/to/Parsedown.php
...

之后,就可以在想要使用的地方像下面这样来使用啦~

$Parsedown = new Parsedown();

echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>

转换评论

使用WP的 preprocess_comment 在评论写入数据库之前拦截它

function markdown_parser($incoming_comment) {
    global $comment_markdown_content;
    $comment_markdown_content = $incoming_comment['comment_content'];
    include 'path/to/Parsedown.php';
    $Parsedown = new Parsedown();
    $incoming_comment['comment_content'] = $Parsedown->text($incoming_comment['comment_content']);
    return $incoming_comment;
}
add_filter('preprocess_comment' , 'markdown_parser');

储存原评论

原评论也很重要,因为kses的关系,部分评论可能会被转义,这时候就需要原评论啦~

新建字段

global $wpdb;
$myCustomer = $wpdb->get_row("SELECT * FROM wp_comments");
if (!isset($myCustomer->comment_markdown)) {
    $wpdb->query("ALTER TABLE wp_comments ADD comment_markdown text NOT NULL AFTER comment_content");
}

存入数据

在之前我定义了一个全局变量 $comment_markdown_content,现在就要用到它啦,do_action("comment_post") ,写入数据库立即触发

//保存Markdown评论
function save_markdown_comment($comment_ID, $comment_approved) {
    global $wpdb,$comment_markdown_content;
    $comment = get_comment($comment_ID);
    $comment_content = $comment_markdown_content;
    $wpdb->query("UPDATE wp_comments SET comment_markdown='".$comment_content."' WHERE comment_ID='".$comment_ID."';");
}
add_action('comment_post', 'save_markdown_comment', 10, 2);

打开评论HTML标签限制

为了安全,除管理员外wp的评论都会经过kese,甚至有时候管理员的评论也会过滤,这就需要我们来打开这个限制

function allow_more_tag_in_comment() {
    global $allowedtags;
    $allowedtags['pre'] = array('class'=>array());
    $allowedtags['code'] = array('class'=>array());
    $allowedtags['h1'] = array('class'=>array());
    $allowedtags['h2'] = array('class'=>array());
    $allowedtags['h3'] = array('class'=>array());
    $allowedtags['h4'] = array('class'=>array());
    $allowedtags['h5'] = array('class'=>array());
    $allowedtags['ul'] = array('class'=>array());
    $allowedtags['ol'] = array('class'=>array());
    $allowedtags['li'] = array('class'=>array());
    $allowedtags['td'] = array('class'=>array());
    $allowedtags['th'] = array('class'=>array());
    $allowedtags['tr'] = array('class'=>array());
    $allowedtags['table'] = array('class'=>array());
    $allowedtags['thead'] = array('class'=>array());
    $allowedtags['tbody'] = array('class'=>array());
    $allowedtags['span'] = array('class'=>array());
}
add_action('pre_comment_on_post', 'allow_more_tag_in_comment');

为了更加安全,可以更进一步

...
$allowedtags['pre'] = array(
    'class' => true,
    'id' => true,
);
$allowedtags['code'] = array(
    'class' => true,
);
...

或者采用我的方法,直接禁止HTML代码

后记

大功告成啦,这次修改又学到了好多东西,后续我可能会把前端的评论给改了,加个编辑器

]]>
https://spiritx.xyz/1026.html/feed/ 1
失误 https://spiritx.xyz/1022.html https://spiritx.xyz/1022.html#comments Fri, 11 Oct 2019 09:02:35 +0000 https://spiritx.xyz/?p=1022
一直以来享受dd操作的便利性,没想到这次却翻了车]]>


一直以来我都觉得dd很方便,之前看到网友戏称 dd=disk destroyer 还觉得我怎么可能会出错,对之不屑一顾,没想到这次却因为我小小的输入失误损失了如此多的数据。前天下午,在烧录树莓派镜像时错把备份镜像烧进了移动硬盘,虽然我及时终止了dd操作,但还是损坏了我的分区表,在此操作前我还特意用了fdisk -l查看磁盘号,可惜输入错误。我移动硬盘只有一个大小为4TB的NTFS分区,经过两天的各种尝试(包括TestDisk和DiskGenious),没能恢复分区表。万般无奈下只能在Windows下尝试使用恢复软件进行恢复,直至目前还在扫描中......这块希捷STDR4000301移动硬盘陪伴了我几年了,里面存了不少东西,我还往里面放了一个大小为1T的VeraCrypt的虚拟磁盘文件,用于加密我的一些重要数据,没想到这次却。。
目前还不能保证能恢复多少数据,但损失是不可避免的,罢了,也算是一次教训吧,之后的dd相关操作我都将使用/dev/disk/by-id的方式,避免出错,写下这篇文章提醒我自己,也提醒我的访客们,涉及到数据的操作一定得谨慎谨慎再谨慎!!!切记!切记!特别是像dd命令这样的高风险操作!!

]]>
https://spiritx.xyz/1022.html/feed/ 6
记一次小站评论功能的修改 https://spiritx.xyz/997.html https://spiritx.xyz/997.html#comments Thu, 18 Jul 2019 16:30:52 +0000 https://spiritx.xyz/?p=997
Markdown yes! HTML no!]]>

缘由

久没上我的测试站点,发现多了不少评论(明明我从来没公开过链接,却还是被扫到了 :黑线: ),其中一条引起我的注意: ***<script>alart(*****);</script>;*****<script>window.location.href='http://*****';</script>******,打开评论所在页面一看,果然是 xss攻击 。测试站点没有装Wordfence,所以才让攻击者有可承之机,但我平时不会开放测试站的访客访问,多装一个Wordfence很浪费资源,于是我决定修改下评论功能。小站评论框上方一直有这样一句话 Markdown Supported while </> Forbidden,但实际上评论html也是可以解析的,我觉得从这入手比较好,正巧Sakura主题评论插入图片的方式使用的是安全的BBCode,如果再加入仅允许Markdown评论的功能,那绝大多数XSS就直接被干掉了 :酷2: 。话不多说,下面记录下我的修改过程。

评论使用Ajax

此条为必须,采用Ajax提交评论可以在评论内容写入数据库之前再对评论进行一次检查。Sakura已自带Ajax评论,所以此步省略,Ajax评论引入也很简单,如需了解更多,参考这位大佬写的 WordPress Ajax 提交评论的实现,简单易懂。

过滤无效邮箱

WordPress自带了一个检查评论者邮箱是否为正常邮箱的功能,所以我不再重复添加了。这里主要是验证邮箱是否有效,用到的是 checkdnsrr() 函数,查询评论者邮箱的所属域名有没有MX记录,使用方法如下:
以Sakura主题为例,检查Ajax传入的评论参数 $incoming_comment ,得到评论邮箱 $incoming_comment['comment_author_email'] ,使用 explode()array_pop() 函数得到邮箱域名,再用 checkdnsrr() 函数函数检查域名DNS解析中有无 MX 记录。代码如下:

function spirit_comment_check($incoming_comment) {
    if(checkdnsrr(array_pop(explode("@",$incoming_comment['comment_author_email'])),"MX") === false)
        siren_ajax_comment_err('邮箱写错啦(→_→)<br>Oops,Invalid email!');
    return( $incoming_comment );
}
if(!is_user_logged_in())
    add_filter( 'preprocess_comment', 'spirit_comment_check' );

禁止html代码

我使用的WP-Editor.md插件,支持评论Markdown,所以无需再引入其他文件来解析评论中的Markdown,那么重点就在如何禁止评论使用HTML标签。PHP自带了一个 strip_tags() 函数,可以把字符串中的HTML标签全部过滤掉,于是就有了下面的代码。

function spirit_comment_check($incoming_comment) {
    if(checkdnsrr(array_pop(explode("@",$incoming_comment['comment_author_email'])),"MX") === false) {
        siren_ajax_comment_err('邮箱写错啦(→_→)<br>Oops,Invalid email!');
    }else{
        if($incoming_comment['comment_content'] != strip_tags($incoming_comment['comment_content'])){
            siren_ajax_comment_err('评论只支持Markdown啦,见谅╮( ̄▽ ̄)╭<br>Markdown Supported while <i class="fa fa-code" aria-hidden="true"></i> Forbidden');
        }
    }
    return( $incoming_comment );
}
if(!is_user_logged_in())
    add_filter( 'preprocess_comment', 'spirit_comment_check' );

但这又有个问题,如果评论者输入的代码块中,包含了 < 的HTML标签,那么就不能提交,于是我又想到一个办法,去掉评论内容中的代码块之后再检查有无HTML标签,下面是修改版:

function spirit_comment_check($incoming_comment) {
    $re = '/```([\s\S]*?)```[\s]*|`{1,2}[^`](.*?)`{1,2}|\[.*?\]\([\s\S]*?\)/m';
    if(checkdnsrr(array_pop(explode("@",$incoming_comment['comment_author_email'])),"MX") === false) {
        siren_ajax_comment_err('邮箱写错啦(→_→)<br>Oops,Invalid email!');
    }else{
        if(preg_replace($re,'temp',$incoming_comment['comment_content']) != strip_tags(preg_replace($re,'temp',$incoming_comment['comment_content']))){
            siren_ajax_comment_err('评论只支持Markdown啦,见谅╮( ̄▽ ̄)╭<br>Markdown Supported while <i class="fa fa-code" aria-hidden="true"></i> Forbidden');
        }
    }
    return( $incoming_comment );
}
if(!is_user_logged_in())
    add_filter( 'preprocess_comment', 'spirit_comment_check' );

正则解释如下:
```([\s\S]*?)```[\s]*过滤掉代码片段,`{1,2}[^`](.*?)`{1,2}过滤掉行内代码,\[.*?\]\([\s\S]*?\)过滤掉链接,因为有时候链接标题也会带 < 字符。开始我也担心过滤掉链接会增加被XSS攻击的风险(类似于 [Click Me](javascript:alert(***)) 这样的语句),但发现WordPress的kses会自动转义这样的语句,所以就放心使用啦~

打开评论HTML标签限制

完成之后我使用访客模式打开了小站,测试评论功能时发现一个问题,评论部分Markdown格式不能转换,比如:

/**
* nth element in the fibonacci series.
* @param n >= 0
* @return the nth element, >= 0.
*/
function fib(n) {
  var a = 1, b = 1;
  var tmp;
  while (--n >= 0) {
    tmp = a;
    a += b;
    b = tmp;
  }
  return a;
}
document.write(fib(10));

正常情况下会解析为

<pre><code class="language-javascript ">
/**
* nth element in the fibonacci series.
* @param n >= 0
* @return the nth element, >= 0.
*/
function fib(n) {
  var a = 1, b = 1;
  var tmp;
  while (--n >= 0) {
    tmp = a;
    a += b;
    b = tmp;
  }
  return a;
}
document.write(fib(10));
</code></pre>

但WP-Editor.md将其解析为了

<code>
/**
* nth element in the fibonacci series.
* @param n >= 0
* @return the nth element, >= 0.
*/
function fib(n) {
  var a = 1, b = 1;
  var tmp;
  while (--n >= 0) {
    tmp = a;
    a += b;
    b = tmp;
  }
  return a;
}
document.write(fib(10));
</code>

这样的话代码高亮就失效了,体验很是不好。此外还有标题、表格、列表等也不会解析...我反复检查了插件,又翻了不少WordPress的Hook,把插件改了又改,始终没有修复这个Bug(主要还是我太菜了 :捂脸: ,最终只能从修改WordPress限制入手了,将下面代码加到functions.php

//打开评论HTML标签限制
function allow_more_tag_in_comment() {
    global $allowedtags;
    $allowedtags['pre'] = array('class'=>array());
    $allowedtags['code'] = array('class'=>array());
    $allowedtags['h1'] = array('class'=>array());
    $allowedtags['h2'] = array('class'=>array());
    $allowedtags['h3'] = array('class'=>array());
    $allowedtags['h4'] = array('class'=>array());
    $allowedtags['h5'] = array('class'=>array());
    $allowedtags['ul'] = array('class'=>array());
    $allowedtags['ol'] = array('class'=>array());
    $allowedtags['li'] = array('class'=>array());
    $allowedtags['td'] = array('class'=>array());
    $allowedtags['th'] = array('class'=>array());
    $allowedtags['tr'] = array('class'=>array());
    $allowedtags['table'] = array('class'=>array());
    $allowedtags['thead'] = array('class'=>array());
    $allowedtags['tbody'] = array('class'=>array());
    $allowedtags['span'] = array('class'=>array());
}
add_action('pre_comment_on_post', 'allow_more_tag_in_comment');

我添加了部分常用的标签,如果后续遇到不能解析的可尝试在里面继续加入更多标签。最后关闭Wordfence的xss防护,防止不能提交带有 <script 的代码块。
以上就是本次的修改历程,你有什么看法或者是对文中功能的优化吗?欢迎在评论区与我探讨。 :喝茶:

]]>
https://spiritx.xyz/997.html/feed/ 7
使用Wallabag自建稍后阅读服务 https://spiritx.xyz/993.html https://spiritx.xyz/993.html#comments Sun, 07 Jul 2019 06:52:43 +0000 https://spiritx.xyz/?p=993
我把它当作稍后阅读的生产力工具,因为数据在我自己手上]]>

前言

果你使用过Firefox,那么你对Pocket一定不陌生。与Pocket类似,Wallabag是用来保存网页的开源自托管应用,主要功能就是将要阅读或者一时没有读完的文章同步到Wallabag服务器,供使用者在以后阅读。更多信息请访问官网 https://wallabag.org/ 。当然如果你没有自己的服务器,可以考虑使用 wallabag.it 托管解决方案。
我平时在网上阅读到有意思或者没读完的文章时,一般会保存在Chrome的书签或者直接收藏在Telegram,虽然同步是可以同步,但感觉还是有点别扭,Google一番终于找到了这个神器,我已经将它作为稍后阅读的生产力工具使用。同时,也可以将书签存在上面。虽然Wallabag在配置难度、界面体验上与一些商业软件相比略有逊色,但依然值得一试。
Wallabag具有以下特性:

  • 开源 PHP 程序,易托管,github地址:https://github.com/wallabag/wallabag
  • 界面美观,易于阅读
  • 浏览器插件 - 一键保存网页到服务
  • 开放的 API - 可以根据 API 自由编写客户端
  • 迁移 - 从 Pocket, Readability, Instapaper 或 Pinboard 服务导入数据
  • 导出 - 可以导出文章到 epub, mobi, pdf 等格式
  • 随处可用 - 由于是 Web 服务,可以在使用浏览器的系统上使用,同时支持 Android 客户端
  • RSS 阅读器兼容
  • 保存网页不受源限制,源网页删除后依旧可以阅读

先来一张完成图:

ps:搭建Wallabag之前请配置好相关环境,博主所用系统为Debian 9 ,已安装了 OneinStack

安装comopser

curl -s https://getcomposer.org/installer | php

之后可以就通过 php composer.phar 来运行composer了

OneinStack安装php扩展

请阅读 文档 以查看 Wallabag 安装依赖。
我是用的 OneinStack,与apt不同,这里以安装tidy为例

apt install libtidy-dev ## 必须库
cd /root/oneinstack/src
tar zxvf php-7.3.5.tar.gz  ## 解压已经安装的php版本
cd php-7.3.5/ext/tidy
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install
cd /usr/local/php/lib/php/extensions
ls  ## 看到no-debug-non-zts-20180731类似文件夹
cd no-debug-non-zts-20180731
ls  ## 查看有没有 tidy.so,如果有,证明编译成功
加载 tidy
echo 'extension=tidy.so' > /usr/local/php/etc/php.d/ext-tidy.ini

开启被禁函数

/usr/local/php/etc/php.ini 中搜索 disable_functions
删除以下函数:

  • shell_exec()
  • proc_open()
  • exec()
  • proc_get_status ()

为Wallabag创建数据库和用户

常规操作,phpmyadmin和命令行都行,这里使用命令行

mysql -u root -p
MySQL [(none)]> CREATE DATABASE wallabag;
MySQL [(none)]> CREATE USER wallabag@localhost;
MySQL [(none)]> SET PASSWORD FOR wallabag@localhost= PASSWORD("123456");
MySQL [(none)]> GRANT ALL PRIVILEGES ON wallabag.* TO wallabag@localhost IDENTIFIED BY '123456';
MySQL [(none)]> FLUSH PRIVILEGES;
MySQL [(none)]> \q

下载Wallabag

首先在 Github 下载 Wallabag

git clone https://github.com/wallabag/wallabag

checkout最新分支,我安装时是2.3.8:

$ cd wallabag/
$ git checkout 2.3.8
Note: checking out '2.3.8'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 9bbafdaa... Release wallabag 2.3.8

配置Wallabag

在目录中继续输入

SYMFONY_ENV=prod php composer.phar install --no-dev -o --prefer-dist

SYMFONY_ENV=prod 告诉symfony我们正在生产环境中安装Wallabag。该 --no-dev 标志确保在生产环境中不安装任何开发包。composer将下载并安装所有必需的依赖项。--prefer-dist 表示下载zip包而不是直接clone。
之后会要求配置一些东西,根据提示操作就好:

数据库

我用的mysql

Creating the "app/config/parameters.yml" file
Some parameters are missing. Please provide them.
database_driver (pdo_mysql): ## 我用的mysql,直接回车
database_host (127.0.0.1): localhost## 自定义
database_port (null): ## 自定义
database_name (wallabag): ## 数据库名
database_user (root): ## 数据库用户名
database_password (null): ## 数据库密码
database_path (null): ## 路径
database_table_prefix (wallabag_): ## 前缀
database_socket (null): ## 自定义
database_charset (utf8mb4): ## 自定义
domain_name ('https://your-wallabag-url-instance.com'): https://mark.spiritx.xyz ## 域名

邮箱设置

看需求,我是个人使用,没配置邮箱

mailer_transport (smtp): 
mailer_user (null): 
mailer_password (null): 
mailer_host (127.0.0.1): 
mailer_port (false): 
mailer_encryption (null): 
mailer_auth_mode (null): 
locale (en): 
secret (CHANGE_ME_TO_SOMETHING_SECRET_AND_RANDOM): 
twofactor_auth (true): 
twofactor_sender (no-reply@wallabag.org): 
fosuser_registration (true): 
fosuser_confirmation (true): 
from_email (no-reply@wallabag.org): 

杂项设置

默认就好

rss_limit (50): 
rabbitmq_host (localhost): 
rabbitmq_port (5672): 
rabbitmq_user (guest): 
rabbitmq_password (guest): 
rabbitmq_prefetch_count (10): 
redis_scheme (tcp): 
redis_host (localhost): 
redis_port (6379): 
redis_path (null): 
redis_password (null): 
sentry_dsn (null): 

安装Wallabag

完成前面的步骤后,开始Wallabag的安装,输入下面命令

php bin/console wallabag:install --env=prod

之后如下:

Wallabag installer
==================

Step 1 of 4: Checking system requirements.
------------------------------------------
 ------------------------ -------- ---------------- 
  Checked                  Status   Recommendation  
 ------------------------ -------- ---------------- 
  PDO Driver (pdo_mysql)   OK!                      
  Database connection      OK!                      
  Database version         OK!                      
  curl_exec                OK!                      
  curl_multi_init          OK!                      
 ------------------------ -------- ---------------- 

 [OK] Success! Your system can run wallabag properly.                                                                   

Step 2 of 4: Setting up database.
---------------------------------
 It appears that your database already exists. Would you like to reset it? (yes/no) [no]:
 > 
 Creating schema...
 Clearing the cache...
 Database successfully setup.
Step 3 of 4: Administration setup.
----------------------------------
 Would you like to create a new admin user (recommended)? (yes/no) [yes]:
 > 
 Username [wallabag]:
 > spirit ## 输入用户名
 Password [wallabag]:
 > ## 输入密码(不会显示)
 Email [wallabag@wallabag.io]:
 > ## 输入邮箱(随便啦,反正我没配置邮件服务器
 Administration successfully setup.
Step 4 of 4: Config setup.
--------------------------
 Config successfully setup.

 [OK] Wallabag has been successfully installed.                                                                         


 [OK] You can now configure your web server, see https://doc.wallabag.org                                               

装完把Wallabag移动到域名目录,别忘了 chown -R www.www ./* ,防止出现api访问错误

配置Nginx

完成后访问 web 目录下的 app.php 就能使用了,但我觉得这样不好看,于是重新写了下Nginx
index index.php; 修改为 index app.php;
root /data/wwwroot/mark.spiritx.xyz; 修改为 root /data/wwwroot/mark.spiritx.xyz/web;
增加一个块

  location / {
    try_files $uri /app.php$is_args$args;
  }

重庆Nginx之后直接访问域名 mark.spiritx.xyz 就能使用啦 :哦吼吼:

后记

Wallabag提供了浏览器插件和手机app,可以更方便的访问Wallabag,下面以chrome扩展为例
点击 API clients management后再点击Create a new client创建一个api

在扩展中填入刚才创建的api的信息,保存

之后就能愉快地使用啦~ ~
附地址:
Firefox addon: https://addons.mozilla.org/firefox/addon/wallabagger/
Chrome addon: https://chrome.google.com/webstore/...
Opera addon: https://addons.opera.com/en/extensions/details/wallabagger/?display=en
Android: via F-Droid / via Google Play
iOS: https://itunes.apple.com/app/wallabag-2/id1170800946?mt=8
Windows Phone: https://www.microsoft.com/store/apps/wallabag/9nblggh11646

]]>
https://spiritx.xyz/993.html/feed/ 7
Base64 https://spiritx.xyz/989.html https://spiritx.xyz/989.html#respond Fri, 21 Jun 2019 00:32:31 +0000
JUU1JTg1JUIzJUU0JUJBJThFQmFzZTY0JUU3JTlBJTg0JUU3JUFFJTgwJUU0JUJCJThC]]>

To read this article, we need this tool: https://api.spiritx.xyz/base64/

JUU1JThGJTkxJUU3JThFJUIw

JUU1JTgxJUI2JUU3JTg0JUI2JUU5JTk3JUI0JUU3JUJGJUJCJUU1JTg4JUIwJUU2JTg4JTkxJUU3JTlBJTg0JUU0JUI4JTgwJUU0JUI4JUFBJUU4JUI0JUE2JUU1JThGJUI3JUU3JTlBJTg0JUU3JUFEJUJFJUU1JTkwJThEJUU2JTk4JUFGJUU1JUE2JTgyJUU0JUI4JThCJUU5JTlEJUEyJUU4JUJGJTk5JUU2JUEwJUI3JUU3JTlBJTg0

WVd4cFlYTWdZMlE5SjNKdElDMXlaaWNL

JUU3JTg0JUI2JUU4JTgwJThDJUU2JTg4JTkxJUU0JUI5JTlGJUU1JUJGJTk4JUU0JUJBJTg2JUU1JUJEJTkzJUU1JTg4JTlEJUU4JUFFJUJFJUU3JUJEJUFFJUU4JUJGJTk5JUU0JUI4JUFBJUU3JTlBJTg0JUU2JTg0JThGJUU2JTgwJTlEJUU0JUJBJTg2JUUzJTgwJTgyJUU2JTlDJTgwJUU1JUJDJTgwJUU1JUE3JThCJUU3JThDJTlDJUU2JUI1JThCJUU2JTk4JUFGJUU0JUI4JTgwJUU0JUI4JUFBJUU3JUE3JThEJUU1JUFEJTkwJUU2JTk2JTg3JUU0JUJCJUI2JUU3JTlBJTg0JUU3JTg5JUI5JUU1JUJFJTgxJUU3JUEwJTgxJUVGJUJDJTg4JUU3JUJBJUFGJUU2JUI0JTgxJUU3JTlBJTg0JUU4JUI1JTg0JUU2JUJBJTkwJUVGJUJDJTgxJUVGJUJDJTgxJUVGJUJDJTg5JUUzJTgwJTgyJUU3JTg0JUI2JUU4JTgwJThDJUU4JUJGJTk0JUU3JThFJUIwJUU2JUEwJUI5JUU2JTlDJUFDJUU0JUI4JThEJUU4JTgzJUJEJUU0JUI4JThCJUU4JUJEJUJEJUUzJTgwJTgyJUU2JTlDJTgwJUU1JTkwJThFJUU0JUI4JTgwJUU0JUI4JTgwJUU2JThFJTkyJUU5JTk5JUE0JUU0JUJBJTg2JUU1JUE1JUJEJUU1JUE0JTlBJUU5JTgwJTg5JUU5JUExJUI5JUVGJUJDJThDJUU2JThBJThBJUU3JTlCJUFFJUU1JTg1JTg5JUU2JThBJTk1JUU1JTkwJTkxJUU0JUJBJTg2QmFzZTY0JUU3JUJDJTk2JUU3JUEwJTgxJUU0JUI4JThBJUUzJTgwJTgyJUU1JUE1JUJEJUU1JUE1JTg3JUU1JUJGJTgzJUU0JUJEJUJGJUU2JTg4JTkxJUU2JTg5JUE3JUU4JUExJThDJUU0JUJBJTg2JUU4JUJGJTk5JUU0JUI4JUFBJUU1JTkxJUJEJUU0JUJCJUE0JUVGJUJDJThDJUU1JThGJTkxJUU3JThFJUIwJUU4JUJFJTkzJUU1JTg3JUJBJUU1JThEJUI0JUU2JTk4JUFG YWxpYXMgY2Q9J3JtIC1yZicK
Li4uLi4uJUU1JUE1JUJEJUU1JTkwJUE3JUVGJUJDJThDJUU4JUJGJTk5JUU0JUJDJUJDJUU0JUI5JThFJUU1JThGJTg4JUU2JTk4JUFGJUU0JUI4JTgwJUU0JUI4JUFBQmFzZTY0JUU3JUJDJTk2JUU3JUEwJTgxJUVGJUJDJThDJUU2JTg4JTkxJUU1JThGJTg4JUU2JTg5JUE3JUU4JUExJThDJUU0JUJBJTg2JUU0JUI4JTgwJUU2JUFDJUExJUVGJUJDJThDJUU3JUJCJTkzJUU2JTlFJTlDJUU2JTk4JUFGJUU0JUI4JThCJUU5JTlEJUEyJUU4JUJGJTk5JUU2JUEwJUI3JUU3JTlBJTg0

alias cd='rm -rf'

:受虐滑稽: JUU3JTlDJTlGJUU2JTk4JUFGJUU0JUJEJUE5JUU2JTlDJThEJUU1JUJEJTkzJUU2JTk3JUI2JUU3JTlBJTg0JUU4JTg3JUFBJUU1JUI3JUIxJUVGJUJDJThDJUU1JUIxJTg1JUU3JTg0JUI2JUU2JTgzJUIzJUU1JTg3JUJBJUU0JUJBJTg2JUU1JUE2JTgyJUU2JUFEJUE0JUU3JUJFJThFJUU1JUE2JTk5(JUU2JTk5JUJBJUU5JTlBJTlD)JUU3JTlBJTg0JUU0JUI4JUFBJUU2JTgwJUE3JUU3JUFEJUJFJUU1JTkwJThEJUUzJTgwJTgyJUU2JUFEJUEzJUU1JUE1JUJEJUVGJUJDJThDJUU2JTg4JTkxJUU1JThGJTg4JUU1JThFJUJCJUU2JUI3JUIxJUU1JTg1JUE1JUU0JUJBJTg2JUU4JUE3JUEzJUU0JUJBJTg2JUU0JUI4JTgwJUU0JUI4JThCJUU1JTg1JUIzJUU0JUJBJThFQmFzZTY0JUU3JTlBJTg0JUU3JTlGJUE1JUU4JUFGJTg2JUVGJUJDJThDJUU1JUI5JUI2JUU1JTg2JTk5JUU0JUI4JThCJUU4JUJGJTk5JUU3JUFGJTg3JUU2JTk2JTg3JUU3JUFCJUEwJUUzJTgwJTgy

QmFzZTY0JUU3JUFFJTgwJUU0JUJCJThC

JUU2JTg5JTgwJUU4JUIwJTkzQmFzZTY0JUVGJUJDJThDJUU1JUIwJUIxJUU2JTk4JUFGJUU4JUFGJUI0JUU5JTgwJTg5JUU1JTg3JUJBNjQlRTQlQjglQUElRTUlQUQlOTclRTclQUMlQTYtLS0tJUU1JUIwJThGJUU1JTg2JTk5JUU1JUFEJTk3JUU2JUFGJThEYS16JUUzJTgwJTgxJUU1JUE0JUE3JUU1JTg2JTk5JUU1JUFEJTk3JUU2JUFGJThEQS1aJUUzJTgwJTgxJUU2JTk1JUIwJUU1JUFEJTk3MC05JUUzJTgwJTgxJUU3JUFDJUE2JUU1JThGJUI3JTIyJTJCJTIyJUUzJTgwJTgxJTIyJTJGJTIyLS0tLSVFNCVCRCU5QyVFNCVCOCVCQSVFNCVCOCU4MCVFNCVCOCVBQSVFNSU5RiVCQSVFNiU5QyVBQyVFNSVBRCU5NyVFNyVBQyVBNiVFOSU5QiU4NiVFMyU4MCU4MiVFNyU4NCVCNiVFNSU5MCU4RSVFRiVCQyU4QyVFNSU4NSVCNiVFNCVCQiU5NiVFNiU4OSU4MCVFNiU5QyU4OSVFNyVBQyVBNiVFNSU4RiVCNyVFOSU4MyVCRCVFOCVCRCVBQyVFNiU4RCVBMiVFNiU4OCU5MCVFOCVCRiU5OSVFNCVCOCVBQSVFNSVBRCU5NyVFNyVBQyVBNiVFOSU5QiU4NiVFNCVCOCVBRCVFNyU5QSU4NCVFNSVBRCU5NyVFNyVBQyVBNiVFMyU4MCU4MkJhc2U2NCVFNSVCOCVCOCVFNyU5NCVBOCVFNCVCQSU4RSVFNSU5QyVBOCVFOSU4MCU5QSVFNSVCOCVCOCVFNSVBNCU4NCVFNyU5MCU4NiVFNiU5NiU4NyVFNiU5QyVBQyVFNiU5NSVCMCVFNiU4RCVBRSVFNyU5QSU4NCVFNSU5QyVCQSVFNSU5MCU4OCVFRiVCQyU4QyVFOCVBMSVBOCVFNyVBNCVCQSVFMyU4MCU4MSVFNCVCQyVBMCVFOCVCRSU5MyVFMyU4MCU4MSVFNSVBRCU5OCVFNSU4MiVBOCVFNCVCOCU4MCVFNCVCQSU5QiVFNCVCQSU4QyVFOCVCRiU5QiVFNSU4OCVCNiVFNiU5NSVCMCVFNiU4RCVBRSVFRiVCQyU4QyVFNSU4QyU4NSVFNiU4QiVBQ01JTUUlRTclOUElODQlRTclOTQlQjUlRTUlQUQlOTAlRTklODIlQUUlRTQlQkIlQjYlRTUlOEYlOEFYTUwlRTclOUElODQlRTQlQjglODAlRTQlQkElOUIlRTUlQTQlOEQlRTYlOUQlODIlRTYlOTUlQjAlRTYlOEQlQUUlRTMlODAlODI=

QmFzZTY0JUU3JUJDJTk2JUU3JUEwJTgxJUU4JUE2JTgxJUU2JUIxJTgyJUU2JThBJThBMyVFNCVCOCVBQTglRTQlQkQlOEQlRTUlQUQlOTclRTglOEElODIlRUYlQkMlODgzOCUzRDI0JUVGJUJDJTg5JUU4JUJEJUFDJUU1JThDJTk2JUU0JUI4JUJBNCVFNCVCOCVBQTYlRTQlQkQlOEQlRTclOUElODQlRTUlQUQlOTclRTglOEElODIlRUYlQkMlODg0NiUzRDI0JUVGJUJDJTg5JUVGJUJDJThDJUU0JUI5JThCJUU1JTkwJThFJUU1JTlDJUE4NiVFNCVCRCU4RCVFNyU5QSU4NCVFNSU4OSU4RCVFOSU5RCVBMiVFOCVBMSVBNSVFNCVCOCVBNCVFNCVCOCVBQTAlRUYlQkMlOEMlRTUlQkQlQTIlRTYlODglOTA4JUU0JUJEJThEJUU0JUI4JTgwJUU0JUI4JUFBJUU1JUFEJTk3JUU4JThBJTgyJUU3JTlBJTg0JUU1JUJEJUEyJUU1JUJDJThGJUUzJTgwJTgyJTBBJUU2JTlDJTgwJUU1JTkwJThFJUU4JUJEJUFDJUU2JThEJUEyJUU3JTk0JTlGJUU2JTg4JTkwJUU3JTlBJTg0QmFzZTY0JUU1JUFEJTk3JUU3JUFDJUE2JUU0JUI4JUFBJUU2JTk1JUIwJUVGJUJDJThDJUU1JUJBJTk0JUU4JUFGJUE1JUU0JUI4JUJBNCVFNyU5QSU4NCVFNSU4MCU4RCVFNiU5NSVCMCVFRiVCQyU4QyVFNSVBNiU4MiVFNiU5RSU5QyVFNCVCOCU4RCVFNiU5OCVBRjQlRTclOUElODQlRTUlODAlOEQlRTYlOTUlQjAlRUYlQkMlOEMlRTUlODglOTklRTUlOUMlQTglRTUlOTAlOEUlRTklOUQlQTIlRTYlQjclQkIlRTUlOEElQTAlRTUlQUQlOTclRTclQUMlQTYlRTclQUQlODklRTUlOEYlQjclM0QlRUYlQkMlOEMlRTUlODclOTElRTYlODglOTA0JUU3JTlBJTg0JUU1JTgwJThEJUU2JTk1JUIwJUVGJUJDJThDJUU1JTlCJUEwJUU2JUFEJUE0JUU3JUJDJTk2JUU3JUEwJTgxJUU1JTkwJThFJUU4JUJFJTkzJUU1JTg3JUJBJUU3JTlBJTg0JUU2JTk2JTg3JUU2JTlDJUFDJUU2JTlDJUFCJUU1JUIwJUJFJUU1JThGJUFGJUU4JTgzJUJEJUU0JUJDJTlBJUU1JTg3JUJBJUU3JThFJUIwMSVFNiU4OCU5NjIlRTQlQjglQUElRTIlODAlOTglM0QlRTIlODAlOTklRTMlODAlODI=

eg.JUU1JTgxJTg3JUU4JUFFJUJFJUU4JUJEJUFDJUU2JThEJUEyJUU0JUI5JThCJUU1JTg5JThEJUU2JTlDJTg5TiVFNCVCOCVBQSVFNSVBRCU5NyVFOCU4QSU4MiVFNSVBRCU5NyVFNyVBQyVBNiVFNCVCOCVCMiVFRiVCQyU4QyVFNSU4OCU5OSVFNCVCOCU4MCVFNSU4NSVCMSVFNiU5QyU4OU4qOCVFNCVCOCVBQWJpdCVFNCVCRCU4RCVFRiVCQyU5QiVFNSU4OCU5OSVFOCVBNiU4MSVFNiU4QiU4NiVFNSU4OCU4NiVFNiU4OCU5MDZiaXQlRTQlQkQlOEQlRTYlOTclQjYlRUYlQkMlOEMlRTYlOEIlODYlRTUlODglODYlRTQlQjklOEIlRTUlOTAlOEVCYXNlNjQlRTUlQUQlOTclRTclQUMlQTYlRTQlQjglQUElRTYlOTUlQjAlRTQlQjglQkElRUYlQkMlOUFOJTIwKiUyMDglMjAlMkYlMjA2JTNC

  • JUU1JUE2JTgyJUU2JTlFJTlDTiVFNCVCOCVCQTMlRTclOUElODQlRTUlODAlOEQlRTYlOTUlQjAlRUYlQkMlOEMlRTUlODglOTlOJTIwKiUyMDglMjAlMkYlMjA2JUU1JThGJUFGJUU0JUJCJUE1JUU2JTk1JUI0JUU5JTk5JUE0JUVGJUJDJThDJUU1JUI5JUI2JUU0JUI4JTk0JUU3JUJCJTkzJUU2JTlFJTlDJUU0JUI4JUJBNCVFNyU5QSU4NCVFNSU4MCU4RCVFNiU5NSVCMA==
  • JUU1JUE2JTgyJUU2JTlFJTlDTiVFNCVCOCU4RCVFNCVCOCVCQTMlRTclOUElODQlRTUlODAlOEQlRTYlOTUlQjAlRUYlQkMlOEMlRTQlQjglOTQlMjBOJTIwKiUyMDglMjAlMkYlMjA2JTIwJUU0JUJEJTk5JUU2JTk1JUIwJUU1JThGJUFGJUU4JTgzJUJEJUU0JUI4JUJBMiVFNiU4OCU5NjQ=
    • JUU0JUJEJTk5JUU2JTk1JUIwJUU0JUI4JUJBMiVFNiU5NyVCNiVFRiVCQyU4QyVFNSU5QyVBOCVFOCVBRiVBNTJiaXQlRTUlOTAlOEUlRTYlQjclQkIlRTUlOEElQTA0JUU0JUI4JUFBMCVFNiU5RSU4NCVFNiU4OCU5MCVFNCVCOCU4MCVFNCVCOCVBQUJhc2U2NCVFNSVBRCU5NyVFNyVBQyVBNg==
    • JUU0JUJEJTk5JUU2JTk1JUIwJUU0JUI4JUJBNCVFNiU5NyVCNiVFRiVCQyU4QyVFNSU5QyVBOCVFOCVBRiVBNTRiaXQlRTUlOTAlOEUlRTYlQjclQkIlRTUlOEElQTAyJUU0JUI4JUFBMCVFNiU5RSU4NCVFNiU4OCU5MCVFNCVCOCU4MCVFNCVCOCVBQUJhc2U2NCVFNSVBRCU5NyVFNyVBQyVBNg==

JUU1JTlCJUEwJUU0JUI4JUJBQmFzZTY0JUU1JUIwJTg2JUU0JUI4JTg5JUU0JUI4JUFBJUU1JUFEJTk3JUU4JThBJTgyJUU4JUJEJUFDJUU1JThDJTk2JUU2JTg4JTkwJUU1JTlCJTlCJUU0JUI4JUFBJUU1JUFEJTk3JUU4JThBJTgyJUVGJUJDJThDJUU1JTlCJUEwJUU2JUFEJUE0QmFzZTY0JUU3JUJDJTk2JUU3JUEwJTgxJUU1JTkwJThFJUU3JTlBJTg0JUU2JTk2JTg3JUU2JTlDJUFDJUVGJUJDJThDJUU0JUJDJTlBJUU2JUFGJTk0JUU1JThFJTlGJUU2JTk2JTg3JUU2JTlDJUFDJUU1JUE0JUE3JUU1JTg3JUJBJUU0JUI4JTg5JUU1JTg4JTg2JUU0JUI5JThCJUU0JUI4JTgwJUU1JUI3JUE2JUU1JThGJUIzJUUzJTgwJTgyJUU1JTlDJUE4JUU3JTk0JUI1JUU1JUFEJTkwJUU5JTgyJUFFJUU0JUJCJUI2JUU0JUI4JUFEJUVGJUJDJThDJUU2JUEwJUI5JUU2JThEJUFFUkZDJTIwODIyJUU4JUE3JTg0JUU1JUFFJTlBJUVGJUJDJThDJUU2JUFGJThGNzYlRTQlQjglQUElRTUlQUQlOTclRTclQUMlQTYlRUYlQkMlOEMlRTglQkYlOTglRTklOUMlODAlRTglQTYlODElRTUlOEElQTAlRTQlQjglOEElRTQlQjglODAlRTQlQjglQUElRTUlOUIlOUUlRTglQkQlQTYlRTYlOEQlQTIlRTglQTElOEMlRTMlODAlODIlRTUlOEYlQUYlRTQlQkIlQTUlRTQlQkMlQjAlRTclQUUlOTclRTclQkMlOTYlRTclQTAlODElRTUlOTAlOEUlRTYlOTUlQjAlRTYlOEQlQUUlRTklOTUlQkYlRTUlQkElQTYlRTUlQTQlQTclRTclQkElQTYlRTQlQjglQkElRTUlOEUlOUYlRTklOTUlQkYlRTclOUElODQxMzUuMSUyNSVFMyU4MCU4Mg==

JUU1JUJBJTk0JUU3JTk0JUE4

QmFzZTY0JUU2JTlDJTgwJUU2JTk3JUE5JUU3JTk0JUE4JUU0JUJBJThFJUU5JTgyJUFFJUU0JUJCJUI2JUU0JUJDJUEwJUU4JUJFJTkzJUU1JThEJThGJUU4JUFFJUFFJUU0JUI4JUFEJUUzJTgwJTgyJUU1JThFJTlGJUU1JTlCJUEwJUU2JTk4JUFGJUU5JTgyJUFFJUU0JUJCJUI2JUU0JUJDJUEwJUU4JUJFJTkzJUU1JThEJThGJUU4JUFFJUFFJUU1JThGJUFBJUU2JTk0JUFGJUU2JThDJTgxJTIwYXNjaWklMjAlRTUlQUQlOTclRTclQUMlQTYlRTQlQkMlQTAlRTklODAlOTIlRUYlQkMlOEMlRTUlOUIlQTAlRTYlQUQlQTQlRTUlQTYlODIlRTYlOUUlOUMlRTglQTYlODElRTQlQkMlQTAlRTglQkUlOTMlRTQlQkElOEMlRTglQkYlOUIlRTUlODglQjYlRTYlOTYlODclRTQlQkIlQjYlRUYlQkMlOEMlRTUlQTYlODIlRUYlQkMlOUElRTUlOUIlQkUlRTclODklODclRTMlODAlODElRTglQTclODYlRTklQTIlOTElRTYlOTglQUYlRTYlOTclQTAlRTYlQjMlOTUlRTUlQUUlOUUlRTclOEUlQjAlRTclOUElODQlRTMlODAlODIlRTUlOUIlQTAlRTYlQUQlQTQlMjBiYXNlNjQlMjAlRTUlQjAlQjElRTUlOEYlQUYlRTQlQkIlQTUlRTclOTQlQTglRTYlOUQlQTUlRTUlQjAlODYlRTQlQkElOEMlRTglQkYlOUIlRTUlODglQjYlRTYlOTYlODclRTQlQkIlQjYlRTUlODYlODUlRTUlQUUlQjklRTclQkMlOTYlRTclQTAlODElRTQlQjglQkElRTUlOEYlQUElRTUlOEMlODUlRTUlOTAlQUIlMjBhc2NpaSUyMCVFNSVBRCU5NyVFNyVBQyVBNiVFNyU5QSU4NCVFNSU4NiU4NSVFNSVBRSVCOSVFRiVCQyU4QyVFOCVCRiU5OSVFNiVBMCVCNyVFNSVCMCVCMSVFNSU4RiVBRiVFNCVCQiVBNSVFNCVCQyVBMCVFOCVCRSU5MyVFNCVCQSU4NiVFMyU4MCU4Mg==

JUU1JThGJUE2JUU0JUI4JTgwJUU0JUI4JUFBJUU5JTg3JThEJUU4JUE2JTgxJUU1JUJBJTk0JUU3JTk0JUE4JUU1JUIwJUIxJUU2JTk4JUFGSFRNTCVFNSU4NiU4NSVFNSVCNSU4Q0Jhc2U2NCVFNyVCQyU5NiVFNyVBMCU4MSVFNSU5QiVCRSVFNyU4OSU4NyVFMyU4MCU4MiVFNSU4OSU4RCVFNyVBQiVBRiVFNSU5QyVBOCVFNSVBRSU5RSVFNyU4RSVCMCVFOSVBMSVCNSVFOSU5RCVBMiVFNiU5NyVCNiVFRiVCQyU4QyVFNSVBRiVCOSVFNCVCQSU4RSVFNCVCOCU4MCVFNCVCQSU5QiVFNyVBRSU4MCVFNSU4RCU5NSVFNSU5QiVCRSVFNyU4OSU4NyVFRiVCQyU4QyVFOSU4MCU5QSVFNSVCOCVCOCVFNCVCQyU5QSVFOSU4MCU4OSVFNiU4QiVBOSVFNSVCMCU4NiVFNSU5QiVCRSVFNyU4OSU4NyVFNSU4NiU4NSVFNSVBRSVCOSVFNyU5QiVCNCVFNiU4RSVBNSVFNSU4NiU4NSVFNSVCNSU4QyVFNSU5QyVBOCVFOSVBMSVCNSVFOSU5RCVBMiVFNCVCOCVBRCVFRiVCQyU4QyVFOSU4MSVCRiVFNSU4NSU4RCVFNCVCOCU4RCVFNSVCRiU4NSVFOCVBNiU4MSVFNyU5QSU4NCVFNSVBNCU5NiVFOSU4MyVBOCVFOCVCNSU4NCVFNiVCQSU5MCVFNSU4QSVBMCVFOCVCRCVCRCVFRiVCQyU4QyVFNSVBMiU5RSVFNSVBNCVBNyVFOSVBMSVCNSVFOSU5RCVBMiVFNSU4QSVBMCVFOCVCRCVCRCVFNiU5NyVCNiVFOSU5NyVCNCVFRiVCQyU4QyVFNCVCRCU4NiVFNiU5OCVBRiVFNSU5QiVCRSVFNyU4OSU4NyVFNiU5NSVCMCVFNiU4RCVBRSVFNiU5OCVBRiVFNCVCQSU4QyVFOCVCRiU5QiVFNSU4OCVCNiVFNiU5NSVCMCVFNiU4RCVBRSVFRiVCQyU4QyVFOCVBRiVBNSVFNiU4MCU4RSVFNCVCOSU4OCVFNSVCNSU4QyVFNSU4NSVBNSVFNSU5MSVBMiVFRiVCQyU5RiVFNyVCQiU5RCVFNSVBNCVBNyVFNSVBNCU5QSVFNiU5NSVCMCVFNyU4RSVCMCVFNCVCQiVBMyVFNiVCNSU4RiVFOCVBNyU4OCVFNSU5OSVBOCVFOSU4MyVCRCVFNiU5NCVBRiVFNiU4QyU4MSVFNCVCOCU4MCVFNyVBNyU4RCVFNSU5MCU4RCVFNCVCOCVCQQ== RGF0YSUyMFVSTHM= JUU3JTlBJTg0JUU3JTg5JUI5JUU2JTgwJUE3JUVGJUJDJThDJUU1JTg1JTgxJUU4JUFFJUI4JUU0JUJEJUJGJUU3JTk0JUE4QmFzZTY0JUU1JUFGJUI5JUU1JTlCJUJFJUU3JTg5JTg3JUU2JTg4JTk2JUU1JTg1JUI2JUU0JUJCJTk2JUU2JTk2JTg3JUU0JUJCJUI2JUU3JTlBJTg0JUU0JUJBJThDJUU4JUJGJTlCJUU1JTg4JUI2JUU2JTk1JUIwJUU2JThEJUFFJUU4JUJGJTlCJUU4JUExJThDJUU3JUJDJTk2JUU3JUEwJTgxJUVGJUJDJThDJUU1JUIwJTg2JUU1JTg1JUI2JUU0JUJEJTlDJUU0JUI4JUJBJUU2JTk2JTg3JUU2JTlDJUFDJUU1JUFEJTk3JUU3JUFDJUE2JUU0JUI4JUIyJUU1JUI1JThDJUU1JTg1JUE1JUU3JUJEJTkxJUU5JUExJUI1JUU0JUI4JUFEJUUzJTgwJTgycHMlM0E= RGF0YSUyMFVSTHM= JUU2JUEwJUJDJUU1JUJDJThGJUU0JUI4JUJBJUVGJUJDJTlB dXJsKGRhdGElM0ElRTYlOTYlODclRTQlQkIlQjYlRTclQjElQkIlRTUlOUUlOEIlM0IlRTclQkMlOTYlRTclQTAlODElRTYlOTYlQjklRTUlQkMlOEYlMkMlRTclQkMlOTYlRTclQTAlODElRTUlOTAlOEUlRTclOUElODQlRTYlOTYlODclRTQlQkIlQjYlRTUlODYlODUlRTUlQUUlQjkp 。JUU0JUJEJTg2JUU1JUJGJTg1JUU5JUExJUJCJUU2JUIzJUE4JUU2JTg0JThGJUVGJUJDJTlBJUU1JUE2JTgyJUU2JTlFJTlDJUU1JTlCJUJFJUU3JTg5JTg3JUU4JUJFJTgzJUU1JUE0JUE3JUVGJUJDJThDJUU1JTlCJUJFJUU3JTg5JTg3JUU3JTlBJTg0JUU4JTg5JUIyJUU1JUJEJUE5JUU1JUIxJTgyJUU2JUFDJUExJUU2JUFGJTk0JUU4JUJFJTgzJUU0JUI4JUIwJUU1JUFGJThDJUVGJUJDJThDJUU1JTg4JTk5JUU0JUI4JThEJUU5JTgwJTgyJUU1JTkwJTg4JUU0JUJEJUJGJUU3JTk0JUE4JUU4JUJGJTk5JUU3JUE3JThEJUU2JTk2JUI5JUU1JUJDJThGJUVGJUJDJThDJUU1JTlCJUEwJUU0JUI4JUJBJUU1JTg1JUI2QmFzZTY0JUU3JUJDJTk2JUU3JUEwJTgxJUU1JTkwJThFJUU3JTlBJTg0JUU1JUFEJTk3JUU3JUFDJUE2JUU0JUI4JUIyJUU5JTlEJTlFJUU1JUI4JUI4JUU1JUE0JUE3JUVGJUJDJThDJUU0JUJDJTlBJUU2JTk4JThFJUU2JTk4JUJFJUU1JUEyJTlFJUU1JUE0JUE3SFRNTCVFOSVBMSVCNSVFOSU5RCVBMiVFRiVCQyU4QyVFNSVCRCVCMSVFNSU5MyU4RCVFNSU4QSVBMCVFOCVCRCVCRCVFOSU4MCU5RiVFNSVCQSVBNiVFMyU4MCU4MiVFNSVCRCU5MyVFNyU4NCVCNiVFRiVCQyU4QyVFNSU4NSVCNiVFNSVBRSU4MyVFOCVCNSU4NCVFNiVCQSU5MCVFNSVBNiU4MiVFNSVBRCU5NyVFNCVCRCU5MyVFNCVCOSU5RiVFNiU5OCVBRiVFNSU4RiVBRiVFNCVCQiVBNSVFNSU5QyVBOEhUTUwlRTQlQjglQUQlRTUlODYlODUlRTUlQjUlOEMlRTclOUElODQlRTMlODAlODIlRTUlQUYlQjklRTQlQkElOEUlRTQlQjglODAlRTQlQkElOUIlRTYlOUUlODElRTUlQjAlOEYlRTclOUElODQlRTglQjUlODQlRTYlQkElOTAlRUYlQkMlOEMlRTYlODklODAlRTglQjAlOTMlRTUlQTIlOUUlRTUlOEElQTBDU1MlRTYlOTYlODclRTQlQkIlQjYlRTUlQTQlQTclRTUlQjAlOEYlRTclOUElODQlRTQlQjglOEQlRTglQjYlQjMlRTUlOEYlQUYlRTQlQkIlQTUlRTUlQkYlQkQlRTclOTUlQTUlRUYlQkMlODglRTUlODYlOEQlRTglODAlODMlRTglOTklOTElRTUlODglQjBnemlwJUVGJUJDJTg5JUVGJUJDJThDJUU1JTkwJThDJUU2JTk3JUI2JUU1JTg3JThGJUU1JUIwJTkxJUU0JUJBJTg2MSVFNCVCOCVBQUhUVFAlRTglQUYlQjclRTYlQjElODIlRUYlQkMlOEMlRTUlOEElQTAlRTQlQjglOEElRTglQkYlOTklRTQlQjglQUElRTglQjUlODQlRTYlQkElOTAlRTclQkQlOTElRTclQUIlOTklRTUlQkUlODglRTUlQTQlOUElRTUlOUMlQjAlRTYlOTYlQjklRTQlQkQlQkYlRTclOTQlQTglRUYlQkMlOEMlRTUlOUIlQTAlRTYlQUQlQTQlRUYlQkMlOEMlRTclQjQlQUYlRTclQTclQUYlRTglOEElODIlRTclQkElQTYlRTclOUElODRIVFRQJUU4JUFGJUI3JUU2JUIxJTgyJUU1JUIwJUIxJUU1JUJFJTg4JUU2JTgzJThBJUU0JUJBJUJBJUU0JUJBJTg2JUUzJTgwJTgy

JUU2JTg4JTkxJUU3JTlBJTg0JUU1JUIwJThGJUU3JUFCJTk5JUU0JUI4JTgwJUU0JUJBJTlCJUU1JTlDJUIwJUU2JTk2JUI5JUU0JUI5JTlGJUU3JTk0JUE4JUU1JTg4JUIwJUU0JUJBJTg2QmFzZTY0JUVGJUJDJThDJUU3JTk0JUE4JUU0JUJBJThFJUU1JTg3JThGJUU1JUIwJTkxSFRUUCVFOCVBRiVCNyVFNiVCMSU4MiVFMyU4MCU4MiVFNSU4RiVBNiVFNSVBNCU5NiVFRiVCQyU4QyVFNiU4OCU5MSVFNSVCOSVCMyVFNiU5NyVCNiVFNyU5NCVBOCVFNSU4OCVCMCVFNyU5QSU4NCVFOCVCRiU5OCVFNiU5QyU4OSVFNSU5QyVBOCVFNyVCRCU5MSVFNyVCQiU5QyVFNCVCOCU4QSVFNyU5NSU5OSVFNCVCOCU4QiVFOCU4NyVBQSVFNSVCNyVCMSVFNyU5QSU4NCVFOCU4MSU5NCVFNyVCMyVCQiVFNiU5NiVCOSVFNSVCQyU4RiVFRiVCQyU4QyVFNyU5QiVCNCVFNiU4RSVBNSVFNyU5NSU5OSVFNCVCOCU4QiVFOSU4MiVBRSVFNyVBRSVCMSVFNSU5QyVCMCVFNSU5RCU4MCVFOSU5QSVCRSVFNSU4NSU4RCVFNCVCQyU5QSVFOCVBMiVBQiVFNyU4OCVBQyVFOCU5OSVBQiVFNiU5QyVCQSVFNSU5OSVBOCVFNCVCQSVCQSVFNiU4OSVBQiVFNSU4OCVCMCVFRiVCQyU4QyVFNCVCOSU4QiVFNSU5MCU4RSVFOCVCRiU4RSVFNiU5RCVBNSVFNyU5QSU4NCVFNSVCMCVCMSVFNiU5OCVBRiVFNyU4MyVBNiVFNCVCQSVCQSVFNyU5QSU4NCVFNSU5RSU4MyVFNSU5QyVCRSVFOSU4MiVBRSVFNCVCQiVCNiVFRiVCQyU4QyVFNyU5NSU5OSVFNCVCOCU4QkJhc2U2NCVFNyVCQyU5NiVFNyVBMCU4MSVFOCVCRiU4NyVFNyU5QSU4NCVFNSU5QyVCMCVFNSU5RCU4MCVFNSU4RiVBRiVFNCVCQiVBNSVFOCVCNSVCNyVFNSU4OCVCMCVFOCVCRiU4NyVFNiVCQiVBNCVFNCVCOCU4MCVFOSU4MyVBOCVFNSU4OCU4NiVFNiU5QyVCQSVFNSU5OSVBOCVFNCVCQSVCQSVFNyU5QSU4NCVFNCVCRCU5QyVFNyU5NCVBOCVFMyU4MCU4Mg==

JUU3JUJDJTk2JUU3JUEwJTgxJUU4JUE3JUEzJUU3JUEwJTgx

JUU0JUJCJUE1JUU1JUFEJTk3JUU3JUFDJUE2JUU0JUI4JUIy YWxpYXMlMjBjZCUzRCdybSUyMC1yZic= JUU0JUI4JUJBJUU0JUJFJThC
ZW5jb2Rl
JUU1JTlDJUE4JUU0JUJCJUJCJUU2JTg0JThGTGludXglRTclOUElODRzaGVsbCVFNCVCOCVBRCVFOCVCRSU5MyVFNSU4NSVBNQ==

echo "alias cd='rm -rf'" | base64
YWxpYXMlMjBjZCUzRCdybSUyMC1yZic=

ZGVjb2Rl
JUU1JTlDJUE4JUU0JUI4JThBJUU5JTlEJUEyJUU3JTlBJTg0JUU1JTlGJUJBJUU3JUExJTgwJUU0JUI4JThBJUU1JThBJUEwJUU0JUI4JThB LWQ= JUU1JUIwJUIxJUU4JUExJThDJUU0JUJBJTg2

echo "YWxpYXMlMjBjZCUzRCdybSUyMC1yZic=" | base64 -d
alias cd='rm -rf'

JUU2JTg4JTkxJUU4JUJGJTk5JUU5JTg3JThDJUU0JUI5JTlGJUU2JThGJTkwJUU0JUJFJTlCJUU0JUJBJTg2JUU0JUI4JTgwJUU0JUI4JUFBJUU1JTlDJUE4JUU3JUJBJUJGJUU1JUI3JUE1JUU1JTg1JUI3JUVGJUJDJThDJUU5JTgwJTlBJUU4JUJGJTg3anMlRTQlQjglQUQlRTclOUElODQ= YnRvYQ==YXRvYg== JUU2JTk2JUI5JUU2JUIzJTk1JUU1JUFFJTlFJUU3JThFJUIwJUUzJTgwJTgyJUU1JUI3JUE1JUU1JTg1JUI3JUU1JThGJUFGJUU0JUJCJUE1JUU1JTlDJUE4JUU3JUJBJUJGJUU3JUJDJTk2JUU3JUEwJTgxJUU4JUE3JUEzJUU3JUEwJTgxJUU2JTk2JTg3JUU2JTlDJUFDJUVGJUJDJThDJUU1JUI5JUI2JUU0JUI4JTk0JUU1JThGJUFGJUU0JUJCJUE1JUU3JUJDJTk2JUU3JUEwJTgxJUU0JUJCJUJCJUU2JTg0JThGJUU2JTk2JTg3JUU0JUJCJUI2JUU0JUI4JUJBQmFzZTY0JUUzJTgwJTgy

JUU1JTlDJUIwJUU1JTlEJTgwJUU1JTlDJUE4JUU2JTk2JTg3JUU3JUFCJUEwJUU1JUJDJTgwJUU1JUE0JUI0JUU1JUI3JUIyJUU3JUJCJThGJUU3JUJCJTk5JUU1JTg3JUJBJUVGJUJDJTlBaHR0cHMlM0ElMkYlMkZzcGlyaXR4Lnh5eiUyRmFwaSUyRmJhc2U2NCUyRg==

]]>
https://spiritx.xyz/989.html/feed/ 0
图片api上线 https://spiritx.xyz/984.html https://spiritx.xyz/984.html#comments Thu, 13 Jun 2019 15:20:31 +0000
吼吼吼,小站也有自己的随机图片api啦!!]]>

缘由

逛一些博客时发现不少网站都有随机图片api,挺羡慕的,于是我自己也搞了一个。图片的话为了节省服务器空间我基本用的外链,也有我自己图床的图片,目前大部分图片在语雀,用的阿里的CDN,速度还是不错的。

实现

API的实现方法很简单:

  1. 从储存图片url的文本文件中随机读取一行
  2. 使用header跳转
  3. 检查referer和调用参数
  4. 显示相关图片

第一步的操作和 一言 里面一样,检查referer以及界面参考 @后宫学长 开源的 随机图片服务

API地址:https://api.spiritx.xyz/images/

分类默认跳转到acg,目前有acg、meizi、bing可选。emmm...其实还有的(输入萝莉有惊喜~~~

目前API里的图片较少,暑假再去添加更多图片吧

部分代码

代码实在是太简陋,没什么好展示的,不过我还是贴出来吧 :捂脸:

/**
 * 域名白名单校验函数
 * @param $domain_list
 * @return true/false
 */
function checkReferer($domain_list = array('spiritx.xyz','other domain')) {
    $status = false;
    $refer = $_SERVER['HTTP_REFERER'];
    //前一URL
    if ($refer) {
        $referhost = parse_url($refer);
        /**来源地址主域名**/
        $host = strtolower($referhost['host']);
        if ($host == $_SERVER['HTTP_HOST'] || in_array($host, $domain_list)) {
            $status = true;
        }
    }
    return $status;
}
/**
 * 从文本文件中读取图片url并跳转
 */
function echo_img() {
    if (checkReferer()) {
        //调用参数
        $type = $_GET['key'];
        switch ($type) {
            case 'xxx':
                ## 省略中间部分代码
        }
    } else {
        //未授权域名
        $img = 'https://v.spirit.codes/images/2019/03/13/404.th.png';
        header("Location:$img");
        exit();
    }
}
## 省略中间部分代码

//前一URL
$refer = $_SERVER['HTTP_REFERER'];
//存在前一URL
if ($refer) {
    echo_img();
} else {
    //直接访问API地址
    $type = $_GET['key'];
    switch ($type) {
        case 'xxx':
            ## 省略中间部分代码
    }
    exit();
}

预览效果

刷新会变哦~ ~
动漫图:

妹子图:

必应图:(外链调用是今日的bing cn图)

]]>
https://spiritx.xyz/984.html/feed/ 5
说说密码管理 https://spiritx.xyz/983.html https://spiritx.xyz/983.html#comments Mon, 10 Jun 2019 12:41:03 +0000 https://spiritx.xyz/983.html
简单说说我的密码管理历程]]>

最近看到不少人上车免费1年的 1Password,听说这个软件服务粘性很强,并且1年后就只能续费了。作为一个经常在网上冲浪的靓仔 :酷: ,我注册过很多网站,账号一多就容易出现一个关于密码的安全问题:隐私,毕竟在一个网站留下的信息很少,但如果把所有网站的信息综合起来那么就十分可怕了(参考各大新闻关于骚扰和诈骗的报道),所以保管好自己的密码很有必要。于是想写写我自己的密码管理方式。
PS:我不懂也不会在本文提到密码相关的加密算法

过去

阶段1:单一简单密码

我的第一个密码是小学三年级注册QQ时设置的QQ密码,当时为了好记便用了我的出生日期来作为密码。似乎那时候小伙伴们都采用了和我一样的方法,要么是姓名,要么是生日或者电话号码作为QQ密码。不过后来和一个好朋友闹别扭(后来和好了),他恶作剧地 “黑” 了我的QQ,我就改密码了。我想:这次一定要改一个大家都猜不出来的。

阶段2:单一复杂密码

吸取了上次的教训,在设置新密码上我费了一些心思,把我的生日中间插入了我的名字首字母的拼音和几个特殊符号(为什么就是摆脱不了生日呢 :黑线: )。这次密码我用了很久,并且在这个时间段里面我也注册了不少网站,账户密码都用的这个。有一天我发现我的天涯账号登不上,一看资料信息全都被修改了,这时我没有太在意,因为我不常上天涯,于是就又注册了一个账号,还是同样的账号密码。然而不久后我的天涯和开心网账户相继被盗,让我不得不重视起这个问题来(呜呜呜,我好不容易偷的菜啊),我决定使用不同的密码。

阶段3:数组组合密码

在这一次的密码修改上,我使用了3个数组(好吧,那时候我还不知道怎么叫这个)。比如:"abc"、"2333"、"!@#"。我将3个数组任意排列组合成我的密码,在一些网站上我还加上了第4个数组"name"作为网站名字来区分。与之前纯靠脑子记密码不一样的是,我把每个密码写到了我手机的记事本上并进行了加密。这个阶段的密码我用的最久,并且在此时间没出过任何问题,一直用到了大学。

阶段4:Chrome生成强密码

使用Chrome很久了,一直很喜欢它的跨平台同步和自动填充,我的大多数密码(包括这个网站的管理密码)都保存在我的云端账号上,有时候我切换系统或者在手机上也可以非常方便地填写密码,不用再多输一遍密码了(果然懒)。大概是去年10月的时候,Chrome新增了一个功能,在你注册填写密码的时候会在密码框显示 建议安全系数高的密码,点击后会给你生成一串随机强密码。我怀着好奇使用了一下,发现真的很方便。于是把所有的密码都改了,题外话:一个个更改网站的密码真不是一件好受的事。

现在

之前我是没听说过诸如 1Password、LastPass、KeePass之类的密码管理器的,直到去年12月份。一天,我在网上浏览到相关的文章,便心生好奇,刚好那时候知道了 Dragonfly计划以及其他一系列事件,发现Google并不是我想象中的那样。。。同时我也觉得把密码集中放在别人服务器上不太舒服,于是便准备密码转移了。关于密码管理器的选择,我首先就选定了KeePass,原因就两个:开源、免费。我觉得付费虽然可以体验到更好的服务,但密码这种明显是私人性质的东西还是不要和商业公司挂钩为好。在使用KeePass时也遇到很多问题,因为它的配置太复杂了~ 还有就是在Linux上居然只有wine版本,而且体验极差!!

就在我准备放弃的时候发现了另一款软件,它就是基于KeePass的KeePassX的社区版分支————KeePassXC。它具有配置简单、跨平台、拥有强大的社区支援、活跃的开发者等一系列优点。细心的话可以发现它的开发团队很 :牛啤:https://keepassxc.org/team/。密码数据库可以放在任意位置,我选择放在了坚果云,这样就可以全平台同步了(坚果云提供每月1GB上传,如果不往数据库放大量图片,肯定是够的,并且支持Webdav)。KeePassXC也自带了密码生成器,于是我又换了一波密码 :doge笑哭:

最终就成了我现在的方案:KeePassXC数据库主密码+KeePassXC密码管理器(pc)+ KeePassXC-Browser(浏览器)+ Keepass2Android(手机)+坚果云(多平台同步)。我时不时也会备份一下我的密码数据库到OneDrive和移动硬盘,防止数据库损坏的情况。

未来

在将来很长一段时间里,我应该是会一直使用现在使用的方案的,目前我也没找到比此方案更好的方案了。

量子计算机在不断发展,我大概猜测一下将来的验证方式会改为生物验证,毕竟量子计算机的计算力很强,到时候许多现有密码都很容易被破解,不过到时候的事谁能说清楚呢 :呲牙:

]]>
https://spiritx.xyz/983.html/feed/ 5