CodingTour
ARTS #56

Algorithm

本周选择的算法题是:字符串的排列

规则如下:

输入一个字符串,打印出该字符串中字符的所有排列。

你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

示例:

输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]

限制:

1 <= s 的长度 <= 8

Solution

Runtime:72 ms,快过 99.67%。

Memory:18.8 MB,低于 100%。

class Solution:
    def permutation(self, s: str) -> List[str]:
        """
        按顺序递推计算。
        以 "abc" 为例,先以 a、b 算出 "ab"、"ba",
        再将 c 分别插入到"ab"和"ba"中。
        """
        visited = set(s[0])
        for i in range(1, len(s)):
            next_visited = set()
            for j in visited:
                for k in range(len(j) + 1):
                    cur = j[:k] + s[i] + j[k:]
                    next_visited.add(cur)
            visited = next_visited.copy()
        return list(visited)

Review

Rollout Swift Support – Under The Hood 一篇关于 Swift 热修复的老文。

它的原理是先用自定义的 swiftc 编译脚本 Hook 住编译流程,然后在 SIL 层为每一个识别到的方法增加一段前缀代码:

if Rollout_shouldPatch(ROLLOUT_a79ee6d5a41da8daaa2fef82124dcf74) {
    let resultRollout : Int = Rollout_invokeReturn(Rollout_tweakData!,target:self, arguments:
    [a,b, origClosure: { args in return self.add(a:args[0],b:args[1]);});
    return resultRollout;
};

这样一来,每个方法都有了一个独一无二的标识:ROLLOUT_a79ee6d5a41da8daaa2fef82124dcf74,在运行时通过服务器下发对应的 JS 脚本替换掉原有的实现,JS 脚本的执行利用了苹果自身的 JSC 框架。

Tip

Timing Attack

时序攻击或者叫计数攻击,这种攻击往往用于攻击一些性能较弱的计算设备,不过也有论文指出利用该方法破解了 OpenSSL 0.9.7 的 RSA 加密算法,这证明这种攻击手段应用到网络攻击中也是可行的。

一些 SDK 中的防范方法

字符串比较

def safeEqual(s1: str, s2: str) -> bool:
    if len(s1) != len(s2): return False
    equal = 0
    for x, y in zip(s1, s2):
        equal |= ord(x) ^ ord(y)
    return equal == 0

这样可以使相同或者不同的字符串比较所耗费的时间一样。

Timing Attacks against String Comparison

Share

做了一张关于HTTP协议版本主要差异的思维导图:

xmind