<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>numbcoder</title>
    <link>https://ruby-china.org/numbcoder</link>
    <description>Simple is better</description>
    <language>en-us</language>
    <item>
      <title>用纯 Ruby 实现了国密 SM2 密码算法</title>
      <description>&lt;p&gt;OpenSSL 自 1.1.1 之后，已经加入了国密标准 SM2/SM3/SM4 算法实现，但是 Ruby 标准库中对 OpenSSL 只是做了一个通用的封装，很多特殊的算法调用需要自己去封装 C API。比如 SM2 就是基于 ECC（椭圆加密算法）的非对称加密算法，同时还能数字签名，Ruby 并没有封装 SM2 的具体 API，好在已经封装了 OpenSSL 中 ECC 和 BigNumber 相关的操作，实现起来比别的语言要省心很多。&lt;/p&gt;

&lt;p&gt;Github 地址：&lt;a href="https://github.com/numbcoder/sm2-crypto" rel="nofollow" target="_blank"&gt;https://github.com/numbcoder/sm2-crypto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;算法实现基于国家密码管理局发布的 &lt;a href="https://www.oscca.gov.cn/sca/xxgk/2010-12/17/1002386/files/b791a9f908bb4803875ab6aeeb7b4e03.pdf" rel="nofollow" target="_blank" title=""&gt;SM2 椭圆曲线公钥密码算法&lt;/a&gt;，详细用法可以参照 Readme 和测试用例&lt;/p&gt;

&lt;p&gt;基本用法：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'sm2_crypto'&lt;/span&gt;

&lt;span class="c1"&gt;# 生成密钥对&lt;/span&gt;
&lt;span class="n"&gt;keypair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PKey&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SM2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keypair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;public_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keypair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_octet_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:uncompressed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 加密&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello, SM2 encryption!"&lt;/span&gt;
&lt;span class="n"&gt;encrypted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SM2Crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 解密&lt;/span&gt;
&lt;span class="n"&gt;decrypted_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SM2Crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encrypted_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 签名&lt;/span&gt;
&lt;span class="n"&gt;sign&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SM2Crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 验签&lt;/span&gt;
&lt;span class="no"&gt;SM2Crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SM3/SM4 是通用实现，可以直接调用，无需自己封装&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# SM3 摘要算法：&lt;/span&gt;
&lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Digest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"sm3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"abc"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SM4 对称加解密&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sm4_decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;decipher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"sm4-ecb"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;decipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;
  &lt;span class="n"&gt;decipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;

  &lt;span class="n"&gt;decipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;decipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;final&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sm4_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;cipher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"sm4-ecb"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;
  &lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;

  &lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;final&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>numbcoder</author>
      <pubDate>Wed, 10 May 2023 17:10:54 +0800</pubDate>
      <link>https://ruby-china.org/topics/43065</link>
      <guid>https://ruby-china.org/topics/43065</guid>
    </item>
    <item>
      <title>[杭州] 杭州络叶科技招聘 Ruby 工程师/算法工程师/UI 设计师</title>
      <description>&lt;p&gt;我们是一家小型的互联网团队，目前主要从事的行业是商用和政务领域的软件研发和视觉设计。
公司在业内的口碑很好，几个产品都是天花板级别的。今年的业务发展好，钱途不错，所以计划扩充一下研发团队。&lt;/p&gt;

&lt;p&gt;我们现在在招的岗位如下：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;后端开发，主要写 Ruby，当然还有一些别的&lt;/li&gt;
&lt;li&gt;算法工程师，做计算机视觉和图像处理领域的算法和 AI 相关的东西&lt;/li&gt;
&lt;li&gt;UI 设计师，主要做 Web 产品的设计，最好有一点平面设计能力&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="后端开发"&gt;后端开发&lt;/h2&gt;
&lt;p&gt;岗位要求：初级、中级&lt;/p&gt;

&lt;p&gt;工作主要是写业务，现有的后端多数是用 Ruby 写的，一些服务有用到 Node.js、Java 等语言。&lt;/p&gt;

&lt;p&gt;当然我们对于你目前掌握的语言其实并不那么看重。因为评价一个人的能力，对于语言的掌握其实是最次要的因素。&lt;/p&gt;

&lt;p&gt;工作并不难，写好业务的关键在于责任心和规划应用结构的能力。&lt;/p&gt;
&lt;h2 id="算法工程师"&gt;算法工程师&lt;/h2&gt;
&lt;p&gt;岗位要求：中级、高级&lt;/p&gt;

&lt;p&gt;目前我们想做的一个新产品是 Linux 客户端软件，功能比较简单，比较复杂的部分是如何处理好图像。&lt;/p&gt;

&lt;p&gt;可能需要日常大部分精力在设计和优化算法，少部分精力用于写一点简单的 Linux 客户端接口，以及对接硬件。&lt;/p&gt;

&lt;p&gt;语言方面没有限制，当然 C、C++ 和 Python 之类的会接触到，其他语言也没问题，新产品你说了算。&lt;/p&gt;
&lt;h2 id="UI设计师"&gt;UI 设计师&lt;/h2&gt;
&lt;p&gt;岗位要求：中级、高级&lt;/p&gt;

&lt;p&gt;需要设计 UI 的地方主要是 Web 类的后台，也会有一些宣传图和包装之类的平面设计的活，不多。&lt;/p&gt;
&lt;h2 id="团队"&gt;团队&lt;/h2&gt;
&lt;p&gt;团队和睦有爱，我们希望所有人都能轻松愉快地做一些有价值的事情。这里没有办公室政治，没有 996，周末 2 天假。&lt;/p&gt;

&lt;p&gt;我们包容各种思想和意识形态，无论是党员还是 LGBT 群体，我们都开放欢迎。&lt;/p&gt;

&lt;p&gt;我们有“分期半价购”买电脑福利，无论是 16"M1 还是 Surface Pro 只要是工作用都行。入职还可以配显示器（目前是 Dell U2720QM）。&lt;/p&gt;

&lt;p&gt;公司位于杭州城西，西溪天街南面。办公环境见：&lt;a href="https://royldesign.cn/about" rel="nofollow" target="_blank"&gt;https://royldesign.cn/about&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;公司网站上主要是一些设计类作品的展示，政务类的产品没有公开。&lt;/p&gt;

&lt;p&gt;我们非常痛恨奇葩的面试题，毫无尊严的面试氛围。所以来的话不需要什么准备，基本就是纯聊天。欢迎有意岗位的朋友过来坐坐。&lt;/p&gt;

&lt;p&gt;Email: alex@royldesign.com&lt;/p&gt;

&lt;p&gt;Twitter: &lt;a href="https://twitter.com/Nemo_A" rel="nofollow" target="_blank" title=""&gt;Nemo_A&lt;/a&gt;&lt;/p&gt;</description>
      <author>numbcoder</author>
      <pubDate>Mon, 25 Oct 2021 20:11:54 +0800</pubDate>
      <link>https://ruby-china.org/topics/41799</link>
      <guid>https://ruby-china.org/topics/41799</guid>
    </item>
    <item>
      <title>Erlang 真的很好！</title>
      <description>&lt;p&gt;趁着 Elixir 1.0 发布之际，我再来鼓吹一下 Erlang 大法！&lt;img title=":smile:" alt="😄" src="https://twemoji.ruby-china.com/2/svg/1f604.svg" class="twemoji"&gt;&lt;/p&gt;

&lt;p&gt;貌似与 Erlang 社区走的最近的也就是 Ruby 社区了，这也就有了 Elixir 的诞生。Erlang 一直是以并发和分布式而著称，但因为 Functional Programming 的语法，导致其一直不被很多开发者接受。&lt;/p&gt;

&lt;p&gt;我接触 Erlang 的时间也不长，但我觉得 Erlang 是真的蛮好的！&lt;/p&gt;

&lt;p&gt;我之前是在 &lt;a href="https://github.com/NetEase/pomelo" rel="nofollow" target="_blank" title=""&gt;Pomelo&lt;/a&gt; 团队，也用 Pomelo 框架开发过几百万连接同时在线，服务器节点上百个的分布式应用，各种坑爹问题都遇到不少，可是直到我真正熟悉了 Erlang/OTP，我才发现这才是我一直想要的东西，其实 Pomelo 一直在做的就是要在 Node.js 上造一个 Erlang！（不过由于 Node.js 异步单线程的特点，所以这个方向也算是走对了）&lt;/p&gt;

&lt;p&gt;下面我来说说 Erlang 的特点：&lt;/p&gt;
&lt;h2 id="工程化"&gt;工程化&lt;/h2&gt;
&lt;p&gt;我不知道这个词形容是否准确，或者叫工业化。Erlang 语言设计的目标非常清晰明确，就是为了构建高并发、分布式网络应用而生。从语言设计层面就已经考虑了很多应用层要考虑的问题，比如说：多核、容错，分布式，负载均衡，代码热更新。我很少见到有编程语言 的设计，会去考虑应用层的东西，一般来说，负载均衡、分布式这些都应该是应用层自己去解决的问题，但是 Erlang 却在语言层面已经帮你做了一定的考虑。&lt;/p&gt;
&lt;h2 id="语法简单"&gt;语法简单&lt;/h2&gt;
&lt;p&gt;Erlang 语法规则非常简单，关键字少，模块清晰，核心 API 也不多，学习起来还是很容易的，关键是要转变以前的语言思维。
模式匹配和递归用起来还是蛮爽的。
Erlang 的 Macro 也很强大，也可以实现很多的 Meta-Programming
Erlang 是动态编译型语言，但是可以通过  &lt;code&gt;spec&lt;/code&gt; 来实现静态类型检测，增强代码健壮性。&lt;/p&gt;
&lt;h2 id="无状态"&gt;无状态&lt;/h2&gt;
&lt;p&gt;Erlang 中的变量一旦赋值，就不可更改了，这也就决定它更容易实现并发。传统语言线程模型需要加锁，来实现线程之间的数据共享，Erlang 则不需要，因为变量赋值之后是不可更改的。传统线程模型通过共享实现线程之间的通讯，而 Erlang 通过通讯来实现进程之间的数据共享。
由于是无状态的，所以 Erlang 能轻易的做代码热更新。&lt;/p&gt;
&lt;h2 id="并发"&gt;并发&lt;/h2&gt;
&lt;p&gt;Erlang 是基于 Actor 模型实现的轻量级进程并发，单台机器可以跑出上百万个轻量级进程
现在比较热门的 Golang 也是以并发性好而大受欢迎，Goroutine 虽然与 Actor 异曲同工，但在分布式和容错性方面，应该是不如 Erlang 的，代码热更新应该也不太容易。
当年号称 Java 杀手的 Scala，说白了其实就是在 JVM 上造了一个 Erlang&lt;/p&gt;
&lt;h2 id="社区"&gt;社区&lt;/h2&gt;
&lt;p&gt;Erlang 的社区看起来是很荒凉的，不像其他语言，开源项目一堆一堆的。其实这是正常的，首先 Erlang 本身就不是为构建 Toy Program 而生的，小工具小网站什么的 Erlang 显然不合适，Couchdb，Rabbitmq 这种才是 Erlang 的拿手好戏。其次就是有 OTP，其他的也就需要一些什么 Http Server，Driver 之类的库了，而这些是都有的。
这里有个 Erlang 资源 &lt;a href="https://github.com/0xAX/erlang-bookmarks/wiki/Erlang-bookmarks" rel="nofollow" target="_blank" title=""&gt;清单&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;而 Ruby 社区看中了 Erlang 平台又想写代码写的更爽一点，所以就在 ErlangVM 上创造了 Elixir，Elixir 和 Erlang 的库是可以共用的。&lt;/p&gt;

&lt;p&gt;所以 Elixir 可以搞起了！&lt;img title=":clap:" alt="👏" src="https://twemoji.ruby-china.com/2/svg/1f44f.svg" class="twemoji"&gt; &lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;PS:  Elixir 在语法规则上比 Erlang 要更复杂一些，也灵活许多，在标准库上也有一些增强，比如 &lt;code&gt;String&lt;/code&gt; ，比 Erlang 方便很多。Erlang 则显得更纯粹，简单直接！  &lt;/p&gt;
&lt;h2 id="重点"&gt;重点&lt;/h2&gt;
&lt;p&gt;我们正在招聘 Erlang / Elixir 工程师，待遇丰厚，有兴趣的拿简历砸我吧!（相信你能找到我的联系方式）&lt;img title=":smile:" alt="😄" src="https://twemoji.ruby-china.com/2/svg/1f604.svg" class="twemoji"&gt;&lt;/p&gt;</description>
      <author>numbcoder</author>
      <pubDate>Sat, 13 Sep 2014 21:36:05 +0800</pubDate>
      <link>https://ruby-china.org/topics/21520</link>
      <guid>https://ruby-china.org/topics/21520</guid>
    </item>
    <item>
      <title>这种牛人是怎样炼成的？</title>
      <description>&lt;p&gt;刚有帖子在讨论 SproutCore，然后又扯到了 Yehuda Katz 大神。
然后我就去了他的博客，看到这么一个介绍
&lt;img src="//l.ruby-china.com/photo/0ab55391d98b35cb477e84d93068f1c8.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;Rails core team,  JQuery core team ,leader of Merb，还有 DataMapper，和最近的 SproutCore。
这简直是前后端通杀，这是怎样做到的，太神了。。
膜拜啊。。。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;坊间传言：每一个伟大的程序，都离不开一脸络腮胡子！&lt;/p&gt;

&lt;p&gt;看到大神的头像，我似乎明白了点什么。一直苦闷自己写不出牛逼的代码，原来我一直缺一样东西。。XD  &lt;/p&gt;</description>
      <author>numbcoder</author>
      <pubDate>Sun, 27 Nov 2011 21:55:28 +0800</pubDate>
      <link>https://ruby-china.org/topics/212</link>
      <guid>https://ruby-china.org/topics/212</guid>
    </item>
  </channel>
</rss>
