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协议版本主要差异的思维导图: