米米的博客

做了一点微小的工作

考完了计算物理(Numerical Analysis),用一张图表达一下心情。感觉像是考了一次高等代数,加一点点统计学。
本来计划寒假里把所有作业的代码整理并开源,结果最近自己审视了一下,愈发感觉代码写得惨不忍睹,就不献丑了。

Curve-Fitting Methods

图片来源:Curve-Fitting

根据国际电子电工委员会 IEC1010-1 的定义,我们把电工工作的区域分为四个等级,分别称作 CAT I,CAT II,CAT III 和 CAT IV。CAT 等级是向下兼容的,也就是说,一块 CAT IV 的表用在 CAT I,CAT II,CAT III 下使用是完全安全的,但是一块 CAT I 的万用表用在 CAT II,CAT III 和 CAT IV 环境下使用就不保证安全了。

CAT 等级对用户意味着什么

CAT 等级意味着对客户的人身安全承诺,它不仅仅是耐高压!CAT 等级严格规定了电气工作人员在不同级别的电气环境中可能遇到的电气设备的类型以及在这样的区域中工作所使用的测量工具必须要遵循的安全标准。CAT 后面的电压数值则表示了他们能够收到电压冲击的上限。
例如,一个 CAT III 600V 的万用表,表示该表可以在 CAT I,II 和 III 区域安全使用,在这三个区域里如果该表收到最高 600V 的电压冲击,表不会对人体安全产生威胁,但是这款表在 CAT IV 域使用时,或者到 700V 的高压冲击的时候,就不能保证同样的安全了。CAT 等级是向下兼容的,也就是说,一块 CAT IV 的表用在 CAT I,CAT II,CAT III 下使用是完全安全的,但是一块 CAT I 的万用表用在 CAT II,CAT III 和 CAT IV 环境下使用就不保证安全了,表可能发生爆炸、燃烧威胁到你的安全。

CAT 等级划分

  • CAT I:通过变压器或者类似设备连接到墙上插座的二次电气线路,例如电子仪器设备类。有保护措施的电子设备、任何高压、低压回路,如办公室内部的复印机等。
  • CAT II:通过电源线连接到室内插座的用电设备的一次电气线路,如移动式工具,家电等。家用电器、便携工具(电钻等)、家用插座,距离三类线路 10 米以上的插座或者距离四类线路 20 米以上的插座。
  • CAT III:直接连接到配电盘的大型设备的一次线路及配电盘与插座之间的电路线路(三相分配电路包括单个商业照明电路)。位置固定的设备,如多相马达、多相闸盒;大型建设物内部的照明设备、线路;工业现场(车间)的机床、电源配电盘等。
  • CAT IV:三相公用供电设备和室外供电线路设备。涉及到「初始连接」的设备,如电站的电力分配系统;电力仪表,前端过置保护,任何室外输电线路。

如何理解 CAT 等级

CAT 等级有各自的工作电压和瞬时峰值电压。CAT 等级的工作电压分为:50V,150V,300V,600V,1000V。工作电压越高意味着能够承受的瞬时峰值电压也越高。
如下表所示:

等级瞬时峰值
CAT IV 600V8kV impulse
CAT III 600V6kV impulse
CAT III 1000V8kV impulse
CAT II 600V4kV impulse
CAT II 1000V6kV impulse

下图有更详细的数据:

CAT III 600V 比 CAT II 1000V 更安全

人们往往无法理解这一点,为什么只能承受 600V 电压的设备的比 1000V 更安全?
这里涉及到信号源阻抗的问题。信号源阻抗越大,CAT 等级越低。由表 1 可知,CAT III 等级的阻抗为 2 欧姆,CAT II 等级的阻抗时 12 欧姆,即 CAT II 等级的源阻抗是 CAT III 等级阻抗的 6 倍。所以,虽然 CAT III 等级的电压虽小,但阻抗也小,电流大,从而能够承受更高能量的信号,所以说 CAT III 600V 比 CAT II 1000V 安全。
同一个 CAT 等级下,工作电压越高,其安全等级也越高(同一 CAT 等级的源阻抗相同)。例如:CAT III 1000V(8kV 瞬时高发)比 CAT II 600V(6kV 瞬时高压)更安全。
如果您需要测试一个电力电路,你应该会用到一个 CAT III 600V 或 CAT IV 600V/CAT III 1000V 的仪表,配套 CAT IV-600V/CAT III-1000V 测试线和探头。

常见问题

问:PicoScope 的 CAT I 等级的高压探头 TA044 为什么配套 CAT III 1000V 等级的探头尖端?是不是厂家弄错了。
答:不是。Pico 所有的高压差分探头配套的都是 CAT III 等级的探头尖端。如下图所示。TA044 整体上是一个在 CAT I 环境中能够安全使用的设备,能够测量的最大单端电压 7kV。探头尖端采用的是工作电压 1000V 的 CAT III 等级,该等级下能够承受的瞬时最大尖峰电压是 8kV,所以 CAT III 等级的探头尖端 用起来更加安全。


本文转载自:CAT 等级

当你的代码出现未定义行为时,你会得到一个 segmentation fault 和一堆损坏的数据。当 Jeff Dean 的代码出现未定义行为时,一个独角兽会踏着彩虹从天而降并给每个人提供免费的冰激凌。

在前面的文章 Base64 编码的原理与实现中,笔者讲到了 Base64 编码的诸多用处,例如编码图片以嵌入 HTML 代码。如果你对此有所了解,同时还是一个炉石玩家,就不难发现,暴雪推出的卡组代码功能,本质上就是用一个 Base64 编码的字符串来存储卡组信息。毕竟,你有时会见到以 = 或者 == 结尾的卡组代码,这正是 Base64 编码的典型特征。

注释

当把卡组代码粘贴到炉石传说时,客户端将忽略以#字符开头的行,这就提供了在卡组代码中插入注释的可能性。一个例外是在卡组代码最前面的,以###开头的第一行。如果可以的话,它将被用作卡组名称。你可以从炉石中复制一套卡组到文本编辑器看看效果。
没有被注释的那一行,包含了除卡组名称外的所有信息。玩家在各大论坛、社区分享卡组时,也往往只需要这一行卡组代码。

DBF ID

为了了解编码的机制,我们需要先介绍 DBF ID。这是每张炉石卡牌(包括可收集卡牌、衍生卡牌、冒险模式专属卡牌、英雄皮肤等)的唯一标识符 —— 是的,这也是能够卡出下图这种 Bug 的原因。皮肤被标记为了一张紫卡。

啦啦啦遇到的Bug

而炉石卡组代码正是使用 DBF ID 来表示每张卡牌。DBF ID 和卡牌的对应关系可在游戏文件中解包得到。更加方便的方法是使用 HearthstoneJSON,这个网站上提供了相关 API 进行查询。你也可以直接通过这个链接下载最新的 cards.collectible.json,这里面包含了所有可收集卡牌的信息,例如各种语言的卡牌名称、描述等。

格式

如前所述,卡组代码是 Base64 编码的字节串,我们先来解码它。许多编程语言都可以做到这一点,以最好的语言 $PHP 为例:

1
2
3
4
5
$deckstring = "AAEBAf0GAA/OBpcHzAjiDP8PyBTmFrasAq6wAqW+Avi/Avm/AqLNAvjQAqbvAgA=";
#这是一个非常有趣的萨满卡组
$binary = base64_decode($deckstring);
$hex = bin2hex($binary);
#对于这个卡组,$hex="00010101fd06000fce069707cc08e20cff0fc814e616b6ac02aeb002a5be02f8bf02f9bf02a2cd02f8d002a6ef0200"

这样就能得到初步解码后的十六进制字符串。如果你不是很擅长编程,也可以搜索一些现成的 Base64 解码工具,看看它是如何工作的。
将这个十六进制字符串按每两个元素一组切割,再把它们转化为无符号整型。也就是说,它们可以是 0x00-0xff,即 0-255。一种实现的方法是这样:

1
2
$arr = str_split($hex, 2);
$arr = array_map("hexdec", $arr);

这样我们就得到了一个数组 $arr,它的每个元素都是 8 位无符号整数。更具体的来说,它的编码方式其实是 varint,一种自解释、不定长的编码方案。炉石卡组代码中包含卡牌 DBF ID 和卡牌数量等信息,它们都是整数,但大小相差很多。如果用定长编码,将会需要大量填 0,并且在未来推出 DBF ID 更大的卡牌后可能会不兼容。而 varint 编码则非常适合炉石卡组的情况。对于 varint,我们还需要进一步的解码,才能读取出有用的信息:

1
2
3
4
5
6
7
8
9
10
11
function read_varint(&$data) {
$shift = 0;
$result = 0;
do {
$c = array_shift($data);
$result |= ($c & 0x7f) << $shift;
$shift += 7;
}
while ($c & 0x80);
return $result;
}

这里的 array_shift 会将数组的第一个元素移出数组,并返回它的值。而 |&<< 等都是位运算的运算符。read_varint 函数完成了解码过程,如果有兴趣的话可以试试用 C 或 Python 实现它。
不断地执行 read_varint($arr),直到取完 $arr 中的元素,就能把内容全部解码出来。解码的结果同样是一个无符号整数的数组,但每个元素的大小不再是只有 8 位,其元素个数也少于原始的 $arr

根据作用,我们可以把卡组代码解码后的这个数组分为两个部分:元数据块和卡牌块。

阅读全文 »
0%