数据库关系代数

SQL等实际查询语言是基于关系代数的,然后加入了一些其他的语法。可以利用这个关系代数计算器帮助理解:RelaX - relational algebra calculator

一、原始运算(6种)

集合运算:
1.并集(υ):select A1 from R union A2 form S
2.补集(-):select A1 from r where A1 not in (select A2 from S)
3.笛卡尔积(×):select * from R , S
![图像 3_lim[256-low].png][1]

选择 (σ):select * from R where P
![图像 21_lim[256-low].png][2]

投影(π):select A1, A2, …, An from R
![图像 2_lim[256-low].png][3]

重命名 (ρ):重命名关系的属性或关系自身。

二、连接

student 表

id          name         class_name
1           张三          一年级
2           李四          二年级
3           王五          三年级
4           黄大          四年级

teacher 表

id          name          class_name
1           李老师         一年级
2           宋老师         二年级
3           王老师         三年级
4           刘老师         六年级

自然连接(⋈):R ⋈ S,相当于先做叉乘,再选择公共属性一样的关系实例。如果没有公共属性的话,那么结果就是叉乘。

SELECT * FROM student INNER JOIN teacher on student.class_name=teacher.class_name;
idnameclass_nameidnameclass_name
1张三一年级1李老师一年级
2李四二年级2宋老师二年级
3王五三年级3王老师三年级

半连接 (⋉)(⋊):R ⋉ S,半连接的结果只是在S中有在公共属性名字上相等的元组所有的R中的元组。

SELECT * FROM student LEFT JOIN teacher on student.class_name=teacher.class_name;
idnameclass_nameidnameclass_name
1张三一年级1李老师一年级
2李四二年级2宋老师二年级
3王五三年级3王老师三年级
4黄大四年级NULLNULLNULL

反连接(▷):R ▷ S,反连接的结果是在S中没有在公共属性名字上相等的元组的R中的那些元组。

SELECT * FROM student RIGHT JOIN teacher on student.class_name=teacher.class_name;
idnameclass_nameidnameclass_name
1张三一年级1李老师一年级
2李四二年级2宋老师二年级
3王五三年级3王老师三年级
NULLNULLNULL4刘老师六年级

除法(÷):R ÷ S,其结果由R中元组到唯一于R的属性名字(就是说只在R表头中而不在S表头中的属性)的限制构成,并且它们与S中的元组的所有组合都存在于R中。
![图像 5_lim[256-low].png][5]

三、外连接

外连接是将左侧关系中与右侧公共属性不等的元组值补填到结果元组集的左侧部分,结果元组集的右侧部分则为填null。
外连接也有三种:

  • 左外连接 (⟕):select * from R left outer join S on <连接条件>
  • 右外连接 (⟖):select * from R right outer join S on <连接条件>
  • 全外连接 (⟗):select * from R full outer join S on <连接条件>

左右外连接是对称的,只是结果的属性顺序不同。全外连接是左右外连接的组合。

四、聚集函数

多数数据库包括五个聚集函数:Sum、Count、Average、Maximum和Minimum。
select <函数名>(column_name) from table_name;

注意:
sqlite中是不支持右外连接和完全外链接。

【译】折射网络 TapDance

什么是折射网络?

今天的大多数审查规避工具使用相同的基本方法:它们加密用户的流量,使其看起来无害,并将其引导到位于被检查网络之外的代理服务器。这导致了一个根本问题:一旦检测器发现代理服务器,代理本身就成为另一个阻止的站点。如果用户可以找到代理服务器,检查器也可以。
在这种竞争中,查找和使用 - 或查找和阻止代理服务器,审查政府享有比审查用户更多的自然,增长的优势。例如,他们可以检查流经他们边界的所有数据,以寻找不受欢迎的活动。依靠友好的服务器的策略不能越来越复杂的国家级审查员,他们可以看到和控制一个国家的整个网络。
折射网络*采取不同的方法。通过与ISP和其他网络运营商的合作,折射将代理功能带到网络的核心,而不是试图隐藏来自审查者的各种代理。这使得审查制度成本更高,因为它阻止审查员选择性地阻止用于提供互联网自由的那些服务器。相反,被审查国家以外的整个网络为用户提供互联网自由,而被审查国家的互联网和参与友好网络之间的任何加密数据交换都可以成为信息自由流通的渠道。

refraction_diagram_20170815.png

官网地址:refraction.network

Node.js 中的安全随机值

并不是所有的随机值都是相等的 - 对于与安全相关的代码,您需要一种特定的随机值。

这篇文章的摘要,如果你不想阅读整个事情:

  • 不要使用Math.random()Math.random()是正确答案的情况极少。不要使用它,除非您已阅读整篇文章,并确定您的案件是必要的。
  • 不要直接使用crypto.getRandomBytes。虽然这是一个CSPRNG,但是在“转换”它时会很容易偏离结果,从而使输出变得更加可预测。
  • 如果要生成随机令牌或API密钥:请使用uuid,特别是uuid.v4()方法。 注意node-uuid它不是一样的包,并且不会产生可靠的安全随机值。
  • 如果要在一个范围内生成随机数:使用random-number-csprng

你应该认真考虑阅读整篇文章,虽然不是那么久:)

“随机”的种类

大概有三种类型的“随机”:

  • 真随机:顾名思义。无随机性,无图案或算法适用。这是否真的存在是有争议的。
  • 不可预测的:不是真正随机的,但是攻击者不可能预测。这就是您所需的安全相关代码 - 只要数据不会被猜到,它怎么生成并不重要。
  • 不规则:这是大多数人认为“随机”的想法。一个例子是一个具有星型场景背景的游戏,其中每个星星被画在屏幕上的“随机”位置。这不是真正随机的,它甚至不是不可预知的 - 它看起来并不像是有视觉上的模式。

不规则的数据是快速生成的,但在安全上而言毫无价值 - 即使看起来似乎没有一个模式,攻击者几乎总是可以预测这些值将会是什么。不规则数据的唯一用处是在视觉上表示的东西,如游戏元素或者在笑话网站上随机产生的短语。

不可预测的数据生成速度有点慢,但对于大多数情况来说仍然足够快,并且很难猜到它将具有抗攻击性。不可预测的数据由所谓的CSPRNG提供。

RNG类型(随机数生成器)

  • CSPRNG: 密码安全伪随机数发生器。这是为了安全目的而产生不可预测的数据。
    PRNG:伪随机数发生器。这是一个更广泛的类别,包括刚刚返回不规则值的CSPRNG和生成器 - 换句话说,您不能依靠PRNG为您提供不可预测的值。

RNG: 随机数生成器。这个术语的含义取决于上下文。大多数人将其用作更广泛的类别,包括PRNG和真正的随机数字生成器。

应使用CSPRNG生成与安全相关的目的(即,存在“攻击者”可能性的任何事物)所需的每个随机值。这包括验证令牌,重置令牌,彩票号码,API密钥,生成的密码,加密密钥等等。

Bias

在Node.js中,最广泛可用的CSPRNG是crypto.randomBytes函数,但是您不应该直接使用它,因为很容易弄乱和“偏离”随机值 - 也就是说,使特定的选择值或值集合。

这个错误的一个常见的例子是当你有少于256种可能性(因为单个字节有256个可能的值)时使用%模运算符。这样做实际上使较低的值比较高的值更可能被挑选。

例如,假设您有36个可能的随机值 - 0-9加上a-z中的每个小写字母。一个天真的实现可能看起来像这样:

let randomCharacter = randomByte % 36;

该代码是破碎和不安全的。通过上面的代码,您基本上创建了以下范围(包括):

0-35保持0-35。
36-71变为0-35。
72-107变成0-35。
108-143成为0-35。
144-179成为0-35。
180-215变成0-35。
216-251变为0-35。
252-255变成0-3。

如果您查看上述范围列表,您会注意到,对于4到35(含)之间的每个randomCharacter有7个可能的值,每个随机字符在0和3(含)之间有8个可能的值。这意味着虽然有一个2.64%的机会获得4到35(含)之间的值,但有一个3.02%的机会获得0到3(含)之间的值。

这种差异可能看起来很小,但是攻击者可以轻松有效地减少暴力事件时所需要的猜测量。而这只是一种方法,您可以使您的随机值不安全,尽管它们最初来自安全的随机源。

那么,如何安全地获取随机值?

在Node.js中:

  • 如果您需要在一定范围内的个别随机数:使用random-number-csprng。
  • 如果您需要API键或令牌:使用uuid(而不是node-uuid!),尤其是uuid.v4()方法。

这两者都使用CSPRNG,并以无偏差(即安全)方式“转换”字节。

如何将 JSON 文件导入到 Node.js 中?

你需要使用 fs 模块进行一些操作。

异步版本

var fs = require('fs');

fs.readFile('/path/to/file.json', 'utf8', function (err, data) {
    if (err) throw err; // we'll not consider error handling for now
    var obj = JSON.parse(data);
});

同步版本

var fs = require('fs');
var json = JSON.parse(fs.readFileSync('/path/to/file.json', 'utf8'));

你想用require导入?再考虑一下!

var obj = require('path/to/file.json');

但是,因为以下几点我并不推荐这种方式:

  1. require 只会读取一次文件,后续调用需要同一个文件将返回缓存副本。如果你想读取一个不断更新的.json文件,这不是一个好主意。你可以使用 hack 技巧,但是在这一点上,使用fs更简单。
  2. 如果你的文件没有.json扩展名,require不会将该文件的内容视为JSON。
  3. require 是同步的。如果你有一个非常大的JSON文件,它会阻塞事件循环。你真的需要使用JSON.parsefs.readFile

真的!请用 JSON.parse

错误处理/安全

如果您不确定传递给JSON.parse()的JSON是否是有效的JSON,请确保在try/catch块中调用JSON.parse()。用户提供的JSON字符串可能会使应用程序崩溃,甚至可能导致安全漏洞。如果解析外部提供的JSON,请做好错误处理。

参考文章:
How to parse JSON using Node.js?

使用Nginx提供WebP图像

用JS判断浏览器类型再替换图片链接终究不是一个好的选择,还是需要一个更底层的方法,本文就介绍了用Nginx提供WebP图像,当然你应该提前准备好相应webP图片。

1. 添加 image/webp webp/etc/nginx/mime.types 从而让 Nginx 识别 MIME 类型。

2./etc/nginx/nginx.conf 中的 http 配置段添加如下:

map $http_accept $webp_suffix {
    default "";
    "~*webp" ".webp";
}

3. 这里以WordPress为例,添加如下规则到/etc/nginx/sites-enabled/example.com

location ~* ^/wp-content/.+\.(png|jpe?g)$ {
    add_header Vary Accept;
    try_files $uri$webp_suffix $uri =404;
}

原理:
浏览器的每个请求头中都带有"Accept"字段,例如Accept:image/webp,image/apng,image/*,*/*;q=0.8;第二步中,我们通过$http_accept拿到请求头中的Accept,~*webp是正则,如果含有webp 那么 $webp_suffix 的值就为 .webp;第三部我们通过try_files 先给uri加上.webp后缀,如果没有找到则使用原有地址,最后如果都匹配不到返回404。

参考文章:
Recipe: serve WebP with nginx conditionally