Passkey

來到了2024年,你還在用一個密碼登入所有網站嗎? 來看看 Passkey 可以怎麼幫助你。

首先,我們來看看密碼的問題: - 你有多少個密碼? - 你的密碼有多長?

我們都聽密碼要長,要複雜,但是你真的能記得所有密碼嗎?許多人會用相同的密碼登入不同的網站,這樣一旦有一個網站被駭客入侵,你的所有帳號都會被盜走。

你可以去 haveibeenpwned 這個網站看看你的密碼有沒有被外洩過,如果有,你就應該趕快換掉。因為根據統計,有81%的資料外洩事故跟遺失密碼有關Report

現在我們了解到密碼的問題,那麼 Passkey 可以怎麼幫助你呢?密碼學家發明了公鑰加密,一個簡單的解釋是,你可以產生一組公鑰和私鑰,你可以把公鑰給別人,別人可以用公鑰加密訊息,但是只有你的私鑰可以解密。這樣你就不用擔心密碼被盜了。比如說Bob公開了他的公鑰P,Alice用P加密了一個訊息M,只有Bob的私鑰S才能解密M。這樣子Alice就可以驗證這個訊息是Bob發出的。

為了方便使用,我們可以使用Google或是Apple的Passkey,這樣你就不用自己管理公鑰和私鑰了。

首先,我們來看看Google的Passkey怎麼設定: 在你的手機上登入 Google的帳號,點選進入 Passkey,然後點選"取得密碼金鑰",之後就可以利用手機的指紋或是臉部辨識來登入你的帳號。

設定完Passkey之後,我們來看看如何使用Passkey登入網站,以下是露天拍賣的設定步驟。用手機網頁或是露天App進入登入後就可以設定。

既然Passkey這麼方便,為什麼不試試看呢? 目前唯一的理由就是支援Passkey的網站還不夠多,但是隨著時間的推移,我相信Passkey會變得越來越普及。

Advent of code

一年一度的 Advent of Code 又開始了,今年是我第一次參加,正好用來練習 Elixir。

Advent of Code 是馬拉松競賽,連續 25 天每天都有一個問題,每天的問題都會有兩個部分,第一部分的問題比較簡單,第二部分的問題會比較難,而且第二部分的問題會跟第一部分的問題有關聯。相對其他程式競賽,Advent of Code 有一個地方很特別,那就是他第二部份的問題的 Input 跟 第一部份是相同的,只是題目會比較難。 做了幾天題目之後,我在解第一部份的問題時,會先猜猜看第二部份的問題會是什麼,然後再來寫第一部份的程式,這樣第二部份的問題就會比較好寫了。

以下分享一些解題心得。

Day 3

Part 1

觀察到每個 row 可以獨立計算,利用兩層迴圈,第一層迴圈是 row,第二層迴圈是 column,從左到右,遇到符號的時候,就把數字記起來。比如說,row的值是

..123*..
. => 0
. => 0
1 => 1
2 => 12
3 => 123
* => 123

當讀到*的時候,就知道把數字是123,因為123旁邊有符號,所以把這個數字記起來。

Part 2

跟 Part 1 一樣,只是要多做一件事情,就是紀錄每個符號連結到的數字有哪些,最後找出連結到兩個數字的符號,然後把這兩個數字相乘。

Day 3 的 source 在 GitHub 上,有興趣的朋友可以看看。

Datascience elixir

Elixir 也很適合資料科學的應用,這篇文章會介紹 Elixir 的資料科學生態系統。

首先我們快速對比 Python 與 Elixir 常用的工具:

Python Elixir
Notebook Livebook
Numpy Nx
Pandas Explorer

Learning elixir

第 N 次學習 Functional Programming Language 就上手。

不論是上古神獸 Lisp,Haskell,或是現代一點的 Scala,如果你跟我一樣嘗試過學習 Functional Programming Language,但是都沒有成功,那麼 Elixir 是你最好的選擇。

Pipe Operation - 括號終結者

我朋友 ypcat 推我入 Elixir 的坑的時候,舉出了一個 Elixir 的優點,那就是 Elixir 的語法很簡單,很像 Ruby,所以學習起來很容易,最重要的是可讀性很高,沒有一堆括號()。

比如說我們要把字串的前後空白去掉,再轉成大寫,然後把 WORLD 換成 Gary,如果用 Python 寫的話,會是這樣:

astr = " Hello world! "
astr.strip().upper().replace("WORLD", "Gary")

這邊可以看到由於 Python 支援 object ,所以字串有 strip, upper, replace 這些 method 可以用,而且這些 method 都會回傳一個新的字串,所以可以一直串起來用。

再來看一下 Elixir 的寫法:

astr = " Hello world! "
String.trim(String.replace(String.upcase(astr), "WORLD", "Gary"))

巢狀的括號看起來是不是很難懂? 這時候就可以用到 Pipe Operation 來改寫:

astr = " Hello world! "
astr |> String.trim() |> String.upcase() |> String.replace("WORLD", "Gary")

背後的原則是,我們可以把這樣的 expression g(f(x)) 改寫成 x |> f() | > g() ,這樣看起來是不是清爽多了?

Thinking Elixir 入門課程

初次學習 Elixir 的朋友, 推薦從這邊開始,有兩堂入門的課程: ThinkingElixir

如果你還沒有 Elixir 的環境,建議可以從 Livebook 開始,Livebook 是一個可以在瀏覽器上執行 Elixir 程式的環境,可以很快的上手 Elixir 的語法。

Elixir 的資料結構

先來比較一下 python 跟 Elixir 的資料結構,特別注意 Elixir 是 functional programming language,所以資料結構都是 immutable 的, 而且沒有 object method,不管是 List 或是 Map 存取都是用 function。

List

Elixir 的 List 跟 Python 的 List 很像,但是同樣的 Elixir 的 List 是 immutable 的,如果修改 List 內的值,會得到新的 List 。 另外 Elixir 的 List 不像是 Array,不能直接存取第 n 個元素。一般 List 的用途是要搭配Pattern,例如 [head | tail] ,之後再說明。

Tuple

Python 的 Tuple 跟 Elixir 的 Tuple 很像,但是 Elixir 的 Tuple 是 immutable 的。

# Python
data = (1, 2, "GO") # Python
data[0] # 1
data[2] # "GO"

# Elixir
data = {1, 2, "GO"}
elem(data, 0) # 1
elem(data, 2) # "GO"
put_elem(t, 2, "foo") # 修改第二個值會傳回一個新的 tuple {1, 2, "foo"}

Map

Elixir 的 Map 跟 Python 的 Dictionary 很像,但是同樣的 Elixir 的 Map 是 immutable 的,如果修改 Map 內的值,會得到新的 Map 。

Python: Dictionary

data = { "name" : "gary" , "age": 99 }

Elixir: Map

產生 Map

data = %{ name: "gary", age: 99, city: "Tokyo" }

注意這裡的 name 是一個 atom (:name)

讀取 Map

data[:name]

寫入 Map

Map.put(data, :name, "bob")

更新 Map

%{data | age: 31, city: "Taipei"}