\ & ¥的顯示

在line chrome extension,常常看到 \ 顯示成 ¥,其實這是因為字型的問題,部分日本字型會有此行為,其中一個是Gothic字型

原因可參考: https://tex.stackexchange.com/questions/406247/yen-%C2%A5-symbol-for-backslash-in-texworks

Some Japanese fonts, e.g., MS, Yu, IPA, and Meiryo, render U+005C (REVERSE SOLIDUS) as a yen symbol while yen symbol is assigned to U+00A5 and 0xA5 in Latin-1 encoding. This stems from the fact that the code point 0x5C in Shift_JIS means yen symbol. Developers of the fonts above decided to employ a yen symbol as a glyph for U+005C so that inexperienced users do not get confused with the change in the appearance of the character. Therefore, what the OP considered as a yen symbol is actually a backslash that mimics a yen symbol (ridiculous phrase but I hope you understand the meaning).

https://tex.stackexchange.com/questions/406247/yen-%C2%A5-symbol-for-backslash-in-texworks

在line chrome app中很明顯是對到了日本字體造成的,仔細去看他的css,會發現

在Gothic字型前是微軟正黑體 但是應該要拼成 Microsoft JhengHei而非MS JhengHei,所以瀏覽器就對到第二個順位的字型,MS PGothic,這也是為什麼會看到 \顯示成¥ 的原因

Posted in Front-end | Leave a comment

boost build with fPIC

在build so檔時如果要static link boost ,出現error message

… can not be used when making a shared object; recompile with -fPIC

需要將boost static build加上PIC的參數

./b2 cxxflags=”-fPIC” link=static install

參考: https://stackoverflow.com/questions/49129115/linking-boost-static-libraries

Posted in C++ Language | Leave a comment

CentOS 7 routing metric modification

nmcli connection modify “enp3s0” ipv4.route-metric 200

綁定多張網卡在同網段時,系統預設會加上route,透過metric的設定可以相規則排序。

範例中透過nmcli將enp3s0的metric設成200

可以看到以下 /etc/sysconfig/network-scripts/ifcfg-enp3s0 的IPV4_ROUTE_METRIC被設定為200,設定完需重新啟動network service

/etc/sysconfig/network-scripts/ifcfg-enp3s0
Posted in System Administration | Leave a comment

Set-Cookie notes

在chrome測試set cookie時,發現有時候http可以set成功,可是有時候會set失敗

通常set cookie失敗,主要是一些條件不符合,例如有Secure字串,可是不是透過https,或是SameSite=None可是沒有Secure

上面這個例子很單純,Path (cookie作用路徑),HttpOnly不讓js code存取cookie,但是瀏覽器卻報錯: This Set-Cookie was blocked because it was not sent over a secure connection and would have overwritten a cookie with the Secure attribute.

在確認server side送出來的Set-Cookie header的確沒有Secure後,查了一下網路資料

https://stackoverflow.com/questions/52763345/browsers-ignore-set-cookie-response-header-if-we-try-to-set-a-cookie-which-was-s

https://www.petefreitag.com/item/857.cfm

上面提到如果browser同時有該網站的http/https cookie,如果在https cookie中有設定Secure,則該屬性會影響到http的Set-Cookie行為

另外參考 https://tools.ietf.org/html/rfc6265#section-8.5

Cookies do not provide isolation by port. If a cookie is readable by a service running on one port, the cookie is also readable by a service running on another port of the same server.

也就是說cookie並未被domain隔離(也就是在同一個網站,http與https的set cookie會干 擾),因此在使用上要格外小心。

Posted in Front-end | Leave a comment

scp from remote to local

要透過ssh從遠端複製檔案到local 有很多工具可用,例如sftp, scp,rsync over ssh

sftp 透過get -r 可以recursively抓下整個資料夾

這邊介紹使用scp方式

scp -p -r remote_server:/dir_path local_path

上面的 -p 是保留檔案的modified time,不然預設複製回來時,檔案時間會是複製時的寫入時間

如同cp一樣,前面的參數是 src 後面是 dest,一般我們在使用scp常常是將local 檔案copy到remote:

scp -r local_dir remote_server:

用法其實很類似,只是src和dest的位置交換了。

其實透過rsync可以更方便的同步資料夾,特別是要檢查檔案時間改變才更新下載時

ref:
https://unix.stackexchange.com/questions/105140/how-to-copy-only-new-files-using-scp-command/205018

Posted in System Administration | Leave a comment

Node.js event .once 使用時機

Node.js EventEmitter裡註冊接收事件一般使用 .on(‘event name’, handler) 的方式,但有一個api是 .once,也就是註冊後觸發listener會自動remove,可參考

https://nodejs.org/docs/latest-v12.x/api/events.html#events_emitter_once_eventname_listener

.once 在一般情境較少用到,原因是處理接收事件常常是跟著發送事件的物件生命週期(例如stream的’data’事件,.once只做一次性的handle,能使用到的情境比較像是需要接收到狀態變更,系統落入A狀態要等待切換到B狀態,因此在A狀態時註冊一個接收切換到B狀態的listener,一旦切換到B狀態就remove listener,等待下一次落入A狀態時再註冊

在Node.js doc介紹stream的地方有個不錯的範例 https://nodejs.org/docs/latest-v12.x/api/stream.html#stream_stream 節錄於下

// Write the data to the supplied writable stream one million times.
// Be attentive to back-pressure.
function writeOneMillionTimes(writer, data, encoding, callback) {
  let i = 1000000;
  write();
  function write() {
    let ok = true;
    do {
      i--;
      if (i === 0) {
        // Last time!
        writer.write(data, encoding, callback);
      } else {
        // See if we should continue, or wait.
        // Don't pass the callback, because we're not done yet.
        ok = writer.write(data, encoding);
      }
    } while (i > 0 && ok);
    if (i > 0) {
      // Had to stop early!
      // Write some more once it drains.
      writer.once('drain', write);
    }
  }
}

可以注意 當writer.write 失敗時,就休息等待’drain’ event,再繼續write,也就是如上描述的 – 等待新的狀態變更。

Posted in nodejs | 1 Comment

two’s complement overflow detection

two’s complement overflow有兩種情況會發生

  • carry in without carry out
  • carry out without carry in

用8 bit signed int為例

-100 + (-30)
    1001 1100
+   1110 0010
------------
  1 0000 0000 <- carry bit
  C S
= 1 0111 1110 

C的位置是carry out(就是我們一般說的carry), S的位置是carry in(就是我們一般說的sign bit)

上面的值是 -130 但是 8bit最小是-128,顯然是overflow

根據上面的規則 屬於 carry out without carry in

再看一個例子

100 + 30
    0110 0100
+   0001 1110
----------------------
  0 1111 1000  <- carry bit
  C S
= 0 1000 0010 

根據上面的規則 屬於 carry in without carry out -> overflow

那要怎麼理解上面的規則呢

這要從overflow可能發生的點看

overflow只有可能發生在

  • 正 + 正 => 負
  • 負 + 負 => 正

有沒有可能 正 + 正 => 正 還是overflow?

這邊可以用一個圓盤來想,將圓盤分成兩半,藍色區為正(包含0),紅色區為負

8bit的signed int 是一個循環的圓盤,加法網順時鐘走,減法往逆時鐘走,加法最多(順時鐘)走127步,減法最多(逆時鐘)走128步,因此127 + 127 最多還是負的 (藍色星星標記的地方),-128 + (-128) = 0最多還是正的區域(非負),因此不會有 正+正=正(overflow) or 負+負 = 負(overflow)的情況發生

最後考慮 正 + 正 = 負 & 負 + 負 = 正

正 +  正
  0xxx 
+ 0xxx
-------
  1xxx <-負
負代表 sign bit = 1,因為 兩個數的sign bit都是0(正),
所以代表有carry in,而carry bit(carry out)也會是0,
因為前一位bit只會有 0 + 0 + 1這種case

負 + 負
  1xxx
+ 1xxx
-------
  0xxx <-正
兩個sign bit = 1要加成變成0 代表
 1 + 1 + (0 carry in) = 10, 有carry out 1

上面也就解釋了兩個overflow detection的規則了

Posted in C Language | Leave a comment

one’s & two’s complement number system

在計算機的底層是用0、1來表示資料,因此人類的符號系統要透過電腦表示就需要做編碼轉換,ASCII、Unicode等都是做此用途,而在(整數)數字系統的編碼,比較常見的有

  • ASCII (將數字用ASCII表示)
    • -200 => 2D 32 30 30
  • BCD
    • 189 => 01 08 09 (packed BCD)
  • one’s complement (assume 8-bit size)
    • 0 => 0000 0000b
    • -0 => 1111 1111b (unsigned = 255)
    • -1=> 1111 1110b (unsigned = 254)
    • 127 => 0111 1111b
    • -127=> 1000 0000b (unsigned = 128)
  • two’s complement (assume 8-bit size)
    • 0 => 0000 0000b
    • -1 => 1111 1111b
    • 127 => 0111 1111b
    • -127 => 1000 0001b

unsigned integer的表示就是很單純的2進位轉換,但當考慮到負數的時候,就有不同的表示法,最直覺的想法就是加一個sign bit

例如:
127 = 0111 1111b
-127 = 1111 1111b
2 = 0000 0010b
-2 = 1000 0010b

但是這樣子的表示法在處理數字運算的時候,硬體的實作上比較麻煩且沒有一致性
因此產生了one’s complement / two’s complement表示法(signed number representation)

one’s complement是對positive number bit pattern做negate運算(1->0, 0->1),two’s complement是在one’s complement的基礎上再offset 1 (negate 後 +1)

one’s complement: 1->0, 0->1 負號數字是 個別bit取1的補數
two’s complement: M + (-M) = 2^N 負號數字是取2^N的補數

現代的計算機在整數表示是以two’s complement,one’s complement system在早期的PDP-1、CDC6600等機器上使用,他的問題主要是整數數字0有兩種可能的表示法

one's complement calculations:
-1 + 1 ==> 1111b 1111b ==> -0 (true for test zero)
 6 - 19 => 6 + (-19) => 0000b 0110b + ~(0001b 0011b)
  0000 0110
+ 1110 1100
--------------------
  1111 0010  negative -> ~(0000 1101) = -13

看起來似乎one’s complement很單純就是按照一般bit加法運算的規則,並且相減就當成 加negate number,但事實上並不是這樣,有carry bit時需要特別處理

 one's complement calculations with carry bit: 
   6 + (-0) =>
  0000 0110
+ 1111 1111
--------------------
1 00000101    5 with carry bit  (expect 6)

在1’s complement運算,碰到carry bit,需要執行 end-around borrow,就是把1補到最後一個bit

  1 00000101    5 with carry bit 
=
    00000101
+          1
--------------------
    00000110 = 6

再看

   19 - 3 =>
  0001 0011
+ 1111 1100
--------------------
1 0000 1111 = 15 with carry bit (expect 16) => should wrap around
  0000 1111
+         1
--------------------
  0001 0000 = 16

在硬體上就是一般的加法器再拉一個carry bit做加法就可以達成

跟two’s complement比,運算要另外處理carry bit,並且浪費了 negative zero的表示空間,two’s complement巧妙地做了offset 1解決上述兩個問題,addition, subtraction, multiplication 運算上跟unsigned integer方法一樣,
carry一律discard

127 = 01111 1111b
-127 = ~(0111 1111b) + 1
     =   1000 0000b + 1
     =   1000 0001b
   15 - 5
  0000 1111
+ 1111 1011
-------------------
1 0000 1010 = 10 with carry

  -2 + (-3)
  1111 1110
+ 1111 1101
-------------------
1 1111 1011 = -5 with carry

two’s complement 的操作也可以這樣理解:

可以想像成 (以1 byte為例) 0 到 + 127 , -128 到 -1 的有限數字循環,
0000 0000   0
0000 0001   1
...
0111 1111   127
1000 0000   -128
...
1111 1110   -2
1111 1111   -1
每一個數字 +1 就會進到下一個數字
-N 代表退後 N步,也就是往前 256 - N步
  1 0000 0000 - N 
= 1 + (1111 1111) - N 
= 1 + (1111 1111 - N) 
= 1 + ~N

因此 減N可以理解成往前 1 + ~N 步 也就是 加 1 + ~N
special case:
-N (負N) = 0 – N = 0 + 1 + ~N = 1 + ~N 也就是negate 再加1

Posted in C Language | Leave a comment

ssl cert – EasyRSA

要產生自簽憑證,可以透過openssl command的方式產生ca, 用ca簽發憑證,不過步驟繁瑣,透過EasyRSA可以快速地完成

https://github.com/OpenVPN/easy-rsa

目前最新版是3.0.7,網路上有些介紹使用v2版本,此處介紹v3版本

解開EasyRSA-3.0.7.tgz

需要修改的是vars檔案,先將vars.example改成vars

裡面的設定大部分使用預設值即可,以下跟機構相關資訊一般會修改,憑證有效時間也可以修改,預設CA是3560天。

set_var EASYRSA_REQ_COUNTRY “US”
set_var EASYRSA_REQ_PROVINCE “California”
set_var EASYRSA_REQ_CITY “San Francisco”
set_var EASYRSA_REQ_ORG “Copyleft Certificate Co”
set_var EASYRSA_REQ_EMAIL “me@example.net”
set_var EASYRSA_REQ_OU “My Organizational Unit”

設定完後首先初始化pki

./easyrsa init-pki

建立CA

./easyrsa build-ca

產生server csr & key, client csr & key

./easyrsa gen-req myserver nopass
./easyrsa gen-req myclient nopass

簽發憑證

./easyrsa sign-req server myserver
./easyrsa sign-req client myclient

產生Diffie-Hellman (DH) parameters file

./easyrsa gen-dh

相關檔案會存放在 pki 、pki/issued、pki/private 目錄

openvpn的ta.key

openvpn –genkey –secret ta.key

參考: https://www.howtoforge.com/tutorial/how-to-install-openvpn-server-and-client-with-easy-rsa-3-on-centos-8/

Posted in System Administration | Leave a comment

C/C++中macro的ifndef

以下節錄一段icu unicode lib的文件裡的sample

#ifndef U_CHARSET_IS_UTF8
#   define U_CHARSET_IS_UTF8 0
#endif

理論上,這類的macro會定義在header file,
而一般header file都會有include guard,所以不會重複include
那為什麼要在U_CHARSET_IS_UTF8再檢查一次是否定義過呢?

主要的原因是發生了不在此header定義了這個macro
可能來自於其他header,也可能來自於compiler參數
例如

g++ … -DU_CHARSET_IS_UTF8=1

這樣就可以透過makefile來做一些動態的macro值改變的處理

Posted in C++ Language | Leave a comment