## 切换至Edge后如何找回Internet Explorer

`HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\`

`{1FD49718-1D00-4B19-AF5F-070AF6D5D54C}`

## Rotating Doughnut Using Matrix Multiplication

My copy of Escher’s artwork got some attention and quite some people asked me, “what kind of programmer are you?”, well, this Youtube video explains it well.

Actually, Joma’s video basically depicted me when in real dev mode. Upon watching this video, I couldn’t wait to re-implement it in Python. However, the initial version is basically a trans-coding of the original C code and was pretty hard to read. So here is a version that actually uses Matrix multiplication in Python (In the mean time, I still have to fix the syntax highlighter…):

``import time``import numpy as np``screen_size = 40``theta_spacing = 0.07``phi_spacing = 0.02``illumination = np.fromiter(".,-~:;=!*#\$@", dtype="<U1")``A = 1``B = 1``R1 = 1``R2 = 2``K2 = 5``K1 = screen_size * K2 * 3 / (8 * (R1 + R2))``def render_frame(A: float, B: float) -> np.ndarray:``"""``Returns a frame of the spinning 3D donut.``Based on the pseudocode from: https://www.a1k0n.net/2011/07/20/donut-math.html``"""``cos_A = np.cos(A)``sin_A = np.sin(A)``cos_B = np.cos(B)``sin_B = np.sin(B)``output = np.full((screen_size, screen_size), " ") # (40, 40)``zbuffer = np.zeros((screen_size, screen_size)) # (40, 40)``cos_phi = np.cos(phi := np.arange(0, 2 * np.pi, phi_spacing)) # (315,)``sin_phi = np.sin(phi) # (315,)``cos_theta = np.cos(theta := np.arange(0, 2 * np.pi, theta_spacing)) # (90,)``sin_theta = np.sin(theta) # (90,)``circle_x = R2 + R1 * cos_theta # (90,)``circle_y = R1 * sin_theta # (90,)``x = (np.outer(cos_B * cos_phi + sin_A * sin_B * sin_phi, circle_x) - circle_y * cos_A * sin_B).T # (90, 315)``y = (np.outer(sin_B * cos_phi - sin_A * cos_B * sin_phi, circle_x) + circle_y * cos_A * cos_B).T # (90, 315)``z = ((K2 + cos_A * np.outer(sin_phi, circle_x)) + circle_y * sin_A).T # (90, 315)``ooz = np.reciprocal(z) # Calculates 1/z``xp = (screen_size / 2 + K1 * ooz * x).astype(int) # (90, 315)``yp = (screen_size / 2 - K1 * ooz * y).astype(int) # (90, 315)``L1 = (((np.outer(cos_phi, cos_theta) * sin_B) - cos_A * np.outer(sin_phi, cos_theta)) - sin_A * sin_theta) # (315, 90)``L2 = cos_B * (cos_A * sin_theta - np.outer(sin_phi, cos_theta * sin_A)) # (315, 90)``L = np.around(((L1 + L2) * 8)).astype(int).T # (90, 315)``mask_L = L >= 0 # (90, 315)``chars = illumination[L] # (90, 315)``for i in range(90):``mask = mask_L[i] & (ooz[i] > zbuffer[xp[i], yp[i]]) # (315,)``zbuffer[xp[i], yp[i]] = np.where(mask, ooz[i], zbuffer[xp[i], yp[i]])``output[xp[i], yp[i]] = np.where(mask, chars[i], output[xp[i], yp[i]])``return output``def pprint(array: np.ndarray) -> None:``"""Pretty print the frame."""``print(*[" ".join(row) for row in array], sep="\n")``if __name__ == "__main__":``for _ in range(screen_size * screen_size):``A += theta_spacing``B += phi_spacing``# clear screen using ANSI control code``print("\x1b[H")``time.sleep(0.05)``pprint(render_frame(A, B))``

## Remote for Raspberry Pi + OSMC Media Center

It is not so difficult to turn your Raspberry into a media center. Installing OSMC is rather straight forward on Raspberry Pi. You just download the  image from OSMC website, write it to an SD card, boot your Raspberry from the SD card and that’s it. However, getting a remote working for your OSMC media center working proved to be rather challenging. This post is to record what I’ve learned from the internet in order to get a working remote.

### What you need:

• Raspberry Pi running OSMC;
• IR Receiver (I’m using VS1838B, shown below);

• Any IR remote with enough buttons;
• A computer to access OSMC remotely;

Now, 3 steps to put all the things to together and have them work correctly.

## Hardware hack and supply chain security

Bloomberg just made big news.

In its recent issue, it featured a cover story: “The Big Hack: How China Used a Tiny Chip to Infiltrate U.S. Companies“, detailed how Chinese military planted malicious chips into motherboards manufactured by Taiwanese supplier, supplying motherboards to a major server provider whose servers were used by almost 30 US companies, including Amazon and Apple. And by  doing this, Chinese military gains potential access to these companies and even US military.

Here’s the malicious chip on the motherboard:

Here’s a illustration of that process directly from their website: 继续阅读Hardware hack and supply chain security

《形而上学》亚里士多德

# 2.1 埃及乘法

\$\$1a=a\$\$                                   （2.1）

\$\$(n+1)a=na+a\$\$                 （2.2）

```int multiply0(int n, int a){
if (n==1) return a;
return multiply0(n-1, a)+a;
}```

Ahmes所描述的算法，这个算法在古希腊被称为“埃及乘法”，而很多现代作者则称之为“俄罗斯农民算法”，建立在如下洞察上：

\$\$ 4a=((a+a)+a)+a=(a+a)+(a+a) \$\$

\$\$a+(b+c)=(a+b)+c \$\$

1        ♦         59
2                  118
4                  236
8        ♦        472
16                944
32      ♦      1888

\$\$41*59=(1*59)+(8*59)+(32*59)\$\$

\$\$n=n/2+n/2\$\$    说明n是偶数
\$\$n=(n-1)/2+(n-1)/2+1\$\$  说明n是奇数

odd(n) 意味着 half(n)=half(n-1)

```int multiply1(int n, int a){
if (n==1) return a;
int result=multiply1(half(n), a+a);
if (odd(n)) result=result +a;
return result;
}```

odd(x)很容易实现，测试x的最低位就可以了，half(x)则可以通过对x进行一次右移实现：

```bool odd(int n) { return n&0x1;}
int half(int n) { return n>>1; }```

multiply1需要进行多少次加法运算？每次调用这个函数，我们需要在a+a的地方进行一次加法，因为我们是不断对n取半，我们需要调用这个函数logn次。在某些时候，我们还需要在result+a的地方进行加法运算，因此加法运算的总次数为：

\$\$\#(n)=logn + v(n)-1\$\$

\$\$\#(15)=3+4-1=6\$\$

```int multiply_by_15(int a){
int b=(a+a)+a;    //b == 3*a
int c+b+b;        //c == 6*a
return (c+c)+b;   //12*a + 3*a
}```

# 2.2 改进算法

`r+na`

```int mult_acc0{int r, int n, int a) {
if (n==1) return r+a;
if (odd(n)){
return mult_acc0(r+a, half(n), a+a);
}else{
return mult_acc0(r, half(n), a+a);
}
}```

```int mult_acc1(int r, int n, int a) {
if (n==1) return r+a;
if (odd(n)) r=r+a;
return mult_acc1(r, half(n), a+a);
}```

• n=1的情况很少发生；
• 如果n是偶数，则完全没有必要判断它还是不是1.

```int mult_acc2(int r, int n, int a) {
if (odd(n)) {
r=r+a;
if (n==1) return r;
}
return mult_acc2(r, half(n), a+a);
}```

```int mult_acc3 (int r, int n, int a) {
if (odd(n)) {
r=r+a;
if (n==1) return r;
}
n=half(n);
a=a+a;
return mult_acc3(r,n,a);
}```

```int mult_acc4(int r, int n, int a) {
while (true) {
if (odd(n)) {
r=r+a;
if (n==1) return r;
}
n=half(n);
a=a+a;
}
}```

```int multiply2(int n, int a) {
if (n==1) return a;
return mult_acc4(a, n-1, a);
}```

```int multiply3(int n, int a) {
while (!odd(n)) {
a=a+a;
n=half(n);
}
if (n==1) return a;
return mult_acc4(a, n-1, a);
}```

```int multiply4(int n, int a) {
while (!odd(n)) {
a=a+a;
n=half(n);
}
if (n==1) return n;
return mult_acc4(a, half(n-1), a+a);
}```

# 2.3 本章的思考

## SSH Logon takes long time?

I’ve been suffering from this on CentOS 7 for quite some time now but haven’t really have time to dig into it.

Just today, I noticed the line after a successful logon:

`Last login: Fri March 27 16:03:23 2016 from gateway.`

Aha, now I know where the time has been spent. The SSHd must have taken a long time to figure out the host name of my login IP.

I’ve suspected this before, but in my sshd_config file, the line “UseDNS” was commented out, so I thought it must be something else.

A simple “man sshd_config” revealed that, “UseDNS yes” is actually the default setting:

`UseDNS  Specifies whether sshd(8) should look up the remote host name and check that the resolved host name for the remote IP address maps back to the very same IP address.  The default is “yes”.`

So I just add “UseDNS no” in the configuration file and restarted sshd. Problem solved.

## A documentary on algorithms

I guess it’s not easy to get journalism and algorithm together. Finally here’s comes a documentary about algorithms, made by BBC – The Secret Rules of Modern Living: Algorithms.

It’s intended for general public, so it’s just a gentle introduction. From Euclid’s algorithm to find greatest common divisor to different sorting algorithms to traveling sales man problem to matching algorithm and eventually to machine learning. The algorithms are well illustrated and explained. It’s just enough to expose the audience to the world of algorithm without intimidating them. More importantly, from what I can see, there’s no misconceptions that are commonly seen in introductions of algorithms made by mass media (except maybe the comparison between bubble sort and merge sort is overly simplified and didn’t take memory consumption into consideration).

One interesting scene in the documentary: President Obama was in an interview and was presented a typical computer science question:

“What is the most efficient way to sort a million 32-bit integers?”

After some hesitation, he actually answered:

“I think Bubble Sort would be the wrong way to go.”

Not bad for a president, I must say. Some say it is staged. But it’s still funny to see how Mr. President tried to circumvent the real question with a safe correct answer. You can see the interview here on YouTube.