不用 AI 挑战? 看看大家的算法水平
有十万亿个字符串,需要从中寻找到和字符串 A 完全相同的字符串有多少个,这些字符串包括 A 的长度为 1 ~ 1000 ,给出最佳算法
我一开始想着是一级:去除长度不一集,二级:双指针逐个两端对比
有十万亿个字符串,需要从中寻找到和字符串 A 完全相同的字符串有多少个,这些字符串包括 A 的长度为 1 ~ 1000 ,给出最佳算法
我一开始想着是一级:去除长度不一集,二级:双指针逐个两端对比
在图像处理领域,我们会遇到如下需求:把图像中的目标物体和背景分开。比如背景用白色表示,目标物体用黑色表示。此时我们知道目标物体的灰度值相互接近,背景灰度值相互接近,那么用大津算法能很好把目标从背景当中区分开来。
比如对于下面这张灰度图片

目标物体是中间黑色的几何物体,我们想让这些物体和背景区分更明显一些,比如让物体为纯黑,背景全白。那么我们就需要找到一个合适的阈值,使图片上灰度值大于这个阈值的像素点为255(白色),灰度值小于阈值的像素点为0(黑色)。也就是变成下面这幅图:

那么大津算法需要处理的就是找到最佳的阈值,让目标和物体尽可能分离开。
为了找到合适的阈值,我们首先观察原图的灰度直方图📊:

这是用 Matlab 对原图形成的灰度直方图,灰度直方图的含义是统计图像中不同灰度值的分布情况。由图我们可以看出两个尖峰,在灰度值为0~20的地方存在一个尖峰,代表原图中有大量像素点灰度值为0~20,经观察我们可以认为这部分对应于目标物体。同理我们可以看出背景的灰度值大多集中于100~140之间,为了让目标和背景区分更加明显,我们想让目标物体的灰度值全为0,背景的灰度值全为255,这种处理手法也称为二值化法。
那么阈值取多少合适呢?从图上看似乎取50~100中的任意一点都可以,但是实际情况并不想参考图那样明显,有些图片背景和目标物体较为接近,我们需要一个算法来找到最优阈值才行。
首先我们思考什么样的东西才能成为一类,而我们又是怎么分类的。对于参考图来说,我们可以认为灰度值接近的为一类,灰度值不接近的不是同一类。那我们又是如何衡量灰度值接近的程度呢?这里面就需要用到方差的概念。
方差相比大家都了解,同一类的物体方差小,不同类的物体方差大。所以对于此图我们希望分类的结果是对于灰度值相近的同一类物体,它的方差最小,称为类内方差最小。灰度值不接近的不同类物体,它的方差大,称为类间方差最大。
所以步骤总结如下:
首先我们要形成参考图的灰度直方图,这样方便我们找到最佳阈值。
接下来我们通过穷举每一个灰度值,计算以此为阈值的类内和类间方差。
找到能形成类内方差最小的或类间方差最大的阈值,这个就是我们要找的最佳阈值。
下面以两类分割讲解下具体的算法,实际上大津算法可以分割多类出来。
因为 Medium 不支持显示 MathJax 语法的公式,所以对这部分感兴趣的直接移步到《大津算法(OTSU)》查看吧。
/* OTSU 算法
* *src 存储灰度图像,width 图像宽,height 图像长
* 返回最佳阈值
*/
int otsu(const int *src, int width, int height)
{
int histogram[256]; //存储灰度直方图,这里为256色灰度
int t,thred;
float wf,wb,ub,uf,curVal,maxVal;
int sumb=0,sumf=0,sumW=0,sumPixel=width*height;
wb=wf=maxVal=0.0f;
//求灰度直方图
memset(histogram,0,sizeof(histogram));
for(i=0;i<width*height;i++)
{
histogram[src[i]]++;
}
for (i=0;i<256;i++)
sumW+=i*histogram[i];
//枚举每个灰度
for(t=0;t<256;t++)
{
//求两类类概率密度
wb+=histogram[t];
wf=sumPixel-wb;
if (wb==0||wf==0)
continue;
//求类均值
sumb+=i*histogram[t];
sumf=sumW-sumb;
ub=sumb/wb;
uf=sumf/wf;
//求当前类间方差
curVal=wb*wf*(ub-uf)*(ub-uf);
if(curVal>maxVal)
{
thred=t;
maxVal=curVal;
}
}
return thred;
}
最近突然对各种加密算法有点感兴趣,想测试一下各个加密算法在加密同样的一段数据时,消耗的时间各是多少。
于是用 Node.js 写了一个小程序完成了计算,并且将结果生成为一张排行榜,很是有趣,发布到这里,说不定以后会用得上的。
测试环境
CPU:i7 4700-MQ @ 2.40GHz
平台:amd64
Node.js v7.4.0
测试数据:8MB 随机二进制文件
对称加密秘钥:8B 随机字符串
源代码
这段小程序的源代码请访问:http://pastebin.com/rEeYHgSy
算法调用简介
我的代码虽然运行于 Node.js,但调用的是其内置模块 crypto,也就是用 C/C++ 编写的加密算法模块,并不是原生 Javascript。并且实际运行时 CPU 占用率为 15%,单核 CPU 满负荷,所以可以反应这些算法的实际运行效率。
输出格式
Hash 算法输出运行时间、结果转换为 hex 后的字符串长度。按算法执行时间升序排列。
对称加密算法输出加密时间、解密时间,以及加密和解密的平均时间。按平均时间升序排列。
测试的算法及特别说明
测试了 Node v7.4.0 中支持的所有 Hash 算法和对称加密算法。比较遗憾没有 chacha20.
其中部分对称加密算法在这个版本的 Node 中是不支持的,已跳过。GCM/CCM 对称加密算法在该版本下只支持加密不支持解密,在结果中标注为了 unknown,并且平均时间直接等于加密时间,但实际上解密时间基本都大于加密时间。
(亏我用的还是 stable 版的 Node,提供了方法一调用却抛出异常,都是坑啊…!)
time↓ retLength name ===================================== 12.38 40 ecdsa-with-SHA1 12.39 40 dsaWithSHA 12.39 40 dss1 12.41 40 ssl3-sha1 12.41 40 DSA-SHA1-old 12.42 40 dsaWithSHA1 12.42 40 DSA-SHA1 12.44 40 sha1 12.45 40 DSA-SHA 12.49 40 dsaEncryption 12.51 40 DSA 12.52 40 sha1WithRSAEncryption 12.54 40 RSA-SHA1-2 12.54 40 RSA-SHA1 14.72 32 RSA-MD4 14.72 32 md4 14.74 32 md4WithRSAEncryption 17.31 32 ssl2-md5 17.33 32 ssl3-md5 17.33 32 md5 17.33 32 RSA-MD5 17.34 32 md5WithRSAEncryption 18.52 128 sha512WithRSAEncryption 18.55 96 sha384 18.55 128 sha512 18.55 96 sha384WithRSAEncryption 18.79 128 RSA-SHA512 19.42 96 RSA-SHA384 21.78 40 sha 21.82 40 shaWithRSAEncryption 22.22 40 RSA-SHA 27.05 56 sha224WithRSAEncryption 27.06 64 sha256WithRSAEncryption 27.27 56 RSA-SHA224 27.37 56 sha224 27.57 64 RSA-SHA256 27.60 64 sha256 57.38 40 rmd160 57.39 40 ripemd160WithRSA 57.39 40 ripemd 57.39 40 ripemd160 57.53 40 RSA-RIPEMD160 78.92 128 whirlpool 657.74 32 mdc2WithRSA 658.35 32 mdc2 659.48 32 RSA-MDC2
cipherTime decipherTime avgTime↓ name ===================================== 26.33 unknown 26.33 id-aes128-GCM 26.49 unknown 26.49 aes-128-gcm 26.52 unknown 26.52 id-aes192-GCM 27.35 unknown 27.35 id-aes256-GCM 27.48 unknown 27.48 aes-192-gcm 27.94 unknown 27.94 aes-256-gcm 25.12 30.89 28.01 aes-128-xts 25.29 30.87 28.08 aes-192-ctr 26.54 31.42 28.98 aes-256-ctr 27.22 31.28 29.25 aes-128-ctr 26.12 32.41 29.26 aes-256-xts 38.23 unknown 38.23 aes-128-ccm 38.29 unknown 38.29 id-aes128-CCM 37.07 43.09 40.08 rc4 25.70 55.17 40.43 aes-192-ecb 26.24 54.79 40.52 aes-128-ecb 25.91 55.21 40.56 aes-256-ecb 41.40 unknown 41.40 id-aes192-CCM 40.07 45.45 42.76 aes-128-ofb 44.35 unknown 44.35 aes-256-ccm 44.58 unknown 44.58 id-aes256-CCM 39.14 54.62 46.88 aes-128-cbc 39.50 55.86 47.68 aes128 45.21 50.54 47.87 aes-128-cfb 46.30 51.85 49.07 aes-256-ofb 41.94 57.43 49.69 aes-192-cbc 44.25 55.84 50.05 aes256 45.72 55.95 50.83 aes-256-cbc 49.21 53.30 51.26 aes-192-cfb 38.77 66.82 52.79 aes-128-cbc-hmac-sha1 51.51 56.69 54.10 aes-256-cfb 44.75 67.53 56.14 aes-256-cbc-hmac-sha1 54.38 59.59 56.98 rc4-hmac-md5 68.07 55.45 61.76 aes192 73.48 50.08 61.78 aes-192-ofb 53.46 81.27 67.36 aes-128-cbc-hmac-sha256 67.95 unknown 67.95 aes-192-ccm 53.43 85.33 69.38 aes-256-cbc-hmac-sha256 92.37 96.32 94.35 camellia-128-cfb 86.76 118.05 102.41 camellia-128-cbc 89.88 119.94 104.91 camellia-128-ecb 115.26 98.84 107.05 camellia-128-ofb 111.06 118.04 114.55 camellia-256-ofb 113.69 117.35 115.52 camellia-256-cfb 113.71 117.39 115.55 camellia-192-cfb 118.05 117.26 117.66 camellia128 107.79 137.33 122.56 camellia256 107.93 137.41 122.67 camellia-192-cbc 107.63 137.71 122.67 camellia192 107.78 137.58 122.68 camellia-256-cbc 109.79 140.16 124.98 camellia-256-ecb 110.63 143.20 126.91 camellia-192-ecb 140.93 116.48 128.70 camellia-192-ofb 131.18 138.02 134.60 cast5-ofb 123.23 152.91 138.07 cast 123.20 153.14 138.17 cast-cbc 124.30 153.77 139.03 cast5-cbc 123.54 154.71 139.12 bf-ecb 128.97 153.40 141.18 blowfish 139.52 143.40 141.46 bf-cfb 129.20 154.59 141.90 bf 128.50 155.55 142.02 bf-cbc 140.97 151.75 146.36 cast5-cfb 160.98 138.92 149.95 bf-ofb 153.84 153.59 153.71 cast5-ecb 169.80 175.30 172.55 seed-ofb 175.17 171.99 173.58 idea-cbc 179.36 197.25 188.30 seed 180.20 199.18 189.69 seed-cbc 204.93 179.90 192.41 seed-cfb 192.36 197.95 195.16 des-ofb 190.88 212.10 201.49 des-cbc 190.91 212.15 201.53 des 200.83 203.79 202.31 des-cfb 190.93 216.70 203.81 desx-cbc 212.52 215.72 214.12 des-ecb 193.71 247.75 220.73 desx 285.34 208.45 246.90 rc2-ecb 287.99 207.70 247.84 rc2-64-cbc 383.14 407.20 395.17 aes-128-cfb8 428.57 433.04 430.80 aes-192-cfb8 472.68 478.71 475.69 des-ede3-ofb 473.08 478.73 475.90 des-ede-ofb 466.29 495.94 481.12 des-ede 466.96 496.02 481.49 des-ede3 469.45 494.77 482.11 des-ede-cbc 470.11 495.39 482.75 des3 480.87 485.29 483.08 des-ede-cfb 471.00 496.02 483.51 des-ede3-cbc 478.58 508.53 493.55 aes-256-cfb8 510.35 485.85 498.10 des-ede3-cfb 1144.31 1161.45 1152.88 camellia-128-cfb8 1433.53 1452.09 1442.81 des-cfb8 1486.53 1500.01 1493.27 camellia-192-cfb8 1490.02 1501.36 1495.69 camellia-256-cfb8 3486.28 3491.02 3488.65 aes-128-cfb1 3742.25 3749.80 3746.02 des-ede3-cfb8 3875.10 3877.43 3876.26 aes-192-cfb1 3990.26 3974.18 3982.22 des-ede3-cfb1 4271.61 4273.34 4272.48 aes-256-cfb1 9526.06 9744.03 9635.05 camellia-128-cfb1 12183.0 12151.8 12167.4 camellia-256-cfb1 12180.5 12200.0 12190.2 camellia-192-cfb1 12273.5 12334.8 12304.2 des-cfb1