2017年8月

引言

在一年多之前,我写了一篇文章《The way to Angular 2 | Part.1》介绍 Angular,最初打算持续完成一个系列,然后在我写完文章之后,Angular 和 TypeScript 都发生了相当大的变化,整个系列也搁浅了。 如今,我打算换一个角度,继续这个系列。

为什么要使用 Angular

angular.io_features

为什么要使用 TypeScript

www.typescriptlang.org_index.htm

- 阅读剩余部分 -

随机数与随机字符串

早前我都使用Math.random()来生成随机数,然后转成16进制字符串来生成随机字符串,后来看到了这个回答(stackoverflow)Math.random() 确实不是一个好的选择,因此我需要更加科学的方法。

window.crypto (Web Cryptography API)

Web Cryptography API 已经是 W3C Recommendation 级别,常见浏览器的近期版本也都已经实现了。 0ivS.png 使用的时候也可以不用担心兼容性问题。

crypto.getRandomValues

crypto.getRandomValues 是我们用来实现随机字符串的主要方法,这个方法从实现和随机性的角度来说,更加高效、可靠。 10.2.1. The getRandomValues method The getRandomValues method generates cryptographically random values. It must act as follows:

  1. If array is not of an integer type (i.e., Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array or UInt8ClampedArray), throw a TypeMismatchError and terminate the algorithm.
  2. If the byteLength of array is greater than 65536, throw a QuotaExceededError and terminate the algorithm.
  3. Overwrite all elements of array with cryptographically random values of the appropriate type.
  4. Return array.
Note Do not generate keys using the getRandomValues method. Use the generateKey method instead.

使用方法就是传入一个 Int 的数组,然后返回被加密之后的数组(覆盖原始数组)。

科学的随机字符串生成方法

知道了crypto.getRandomValues的使用方法之后,我们就可以来实现一个科学的随机字符串生成方法了。 首先毫无疑问我们需要一个 UintArray,这比我们手动生成随机数的数组要简单多了。

let len = 64;
const arr = new Uint8Array(len / 2);

假设我们要生成长度为 64 的随机字符串,len 就是 64,之所以在生成 Uint8Array 时候,要将长度除以2,是因为最终我们是通过16进制字符串的形式来输出的,并且在头部补0取末尾两位,所以只需要一半长度的 Uint8Array 就可以了。 用crypto.getRandomValues()加密这个数据

window.crypto.getRandomValues(arr);

把这个 Uint8Array 转换成普通数组,并且把每一个值转换成16进制字符串(首位补0),取末尾2位,最后拼接到一起,就是最终的随机字符串了。

// dec2hex :: Integer -> String
function dec2hex (dec) {
  return ('0' + dec.toString(16)).substr(-2);
}
    
// generateId :: Integer -> String
function generateId (len = 40) {
  const arr = new Uint8Array(len / 2);
  window.crypto.getRandomValues(arr);
  return Array.from(arr, dec2hex).join('');
}

使用这个方法来生成随机字符串,更加高效、科学、可靠。 gist: Generate random string/characters in JavaScript

问题

出于个人习惯,我在终端模拟器(iTerm2 等)中,都是将光标(cursor)设置为 vertical bar,而在 neovim 中则是将 normal 模式的光标设置为 block。

这样一来,当我从 neovim 的正常模式退出时,导致终端的光标样式也变成了 block,非常麻烦。主要是因为终端没有提供 API 查询当前的光标样式设置,因此 neovim 在退出时也不知道要如何重设光标。

解决

思路就是退出 neovim 的时候把光标重新设置为 vertical bar(ver25)。

if $TERM_PROGRAM =~ "iTerm"
  " reset cursor when vim exits
  au VimLeave * set guicursor=a:ver25-blinkon0
endif

其中ver25就是想要设置的样式,也可以是block等等,这样在退出 neovim 的时候就会重新将 iTerm2 的光标设置为 vertical bar。