原文: cs50.harvard.edu/x/2022/psets/1/credit
開始
打開 VS Code.
點擊你的 terminal 視窗,然後輸入 cd
。你會看到他顯示下面的圖示。
$
點擊 terminal 視窗並執行
wget https://cdn.cs50.net/2021/fall/psets/1/credit.zip
按下 Enter 之後就會下載一個 ZIP 檔案叫做 credit.zip。
請注意不要忽略掉 wget
跟後面 URL 中間的空格 以及其他的字。
現在執行
unzip credit.zip
就會建立一個資料夾叫 credit
。
這樣你就不需要 ZIP 檔案了,所以你可以輸入
rm credit.zip
接著,輸入 "y" 跟 Enter 來回覆是否刪除你剛剛下載的 ZIP 檔案。
接著輸入
cd credit
Enter 之後會進入到那個資料夾。你的視窗現在應該會顯示
credit/ $
上面都成功的話,你應該可以執行
ls
你會看到名為 credit.c
的檔案。
執行 code credit.c
應該會打開那個檔案,你可以把這次題目要求的程式寫在這裡。
如果沒有,請重新檢視前面的步驟是否有哪邊做錯了!
信用卡
信用卡就是一張你可以用來購買商品或服務的塑膠卡片。
其卡片編號被記錄在資料庫中,所以當你透過卡片購買商品時,信貸機構可以知道向誰索取款項。
這世界上有很多人都持有信用卡,所以卡片編號會非常長:
美國運通 使用 15 碼 數字,萬事達 有 16 碼 數字,Visa 有 13 - 16 碼 數字。
而這些都是十進位數字 (0 到 9), 並非二進制。
例如,美國運通 可以印 10^15 = 1,000,000,000,000,000 不重複的卡片!
其實,這太誇大了,因為信用卡號實際也是有些規則存在的。
所有 美國運通的卡號開頭必須是 34 或是 37 ,
大部分的 萬事達卡開頭是 51, 52, 53, 54, 55 (當然還是有些例外,不過我們目前不考慮這個),還有 Visa 開頭都是 4.
信用卡號也是有內建一種叫校驗和的機制,至少有一碼數字跟其他數字會有一種數學關係。
這種檢核機制讓電腦 (或是某些喜歡數學的人) 可以檢驗 錯誤輸入,
避免不必要的搜尋資料庫(因為很慢),就能辨識是偽造的卡號。
當然,別有居心的數學家還是可以捏造出這個數字,
所以嚴格來說,資料庫的搜尋還是有必要的。
Luhn's Algorithm
那麼那個神秘的公式是什麼呢?
大部分的信用卡使用的演算法是使用 IBM 的 Hans Peter Luhn 開發的。
根據 Luhn 的演算法,你可以透過以下方式判斷信用卡號是否合格:
- 從第二碼開始到最後一碼,偶數位數字乘 2,並將得到的各個位數的數字再次加總。
- 將原本卡號其餘碼數字加總後,跟前一個式子的結果再次相加。
- 如果最後一碼數字為 0,則卡號合格。
似乎有點困惑,我們來用 David 的 Visa 做個示範:4003600000000014。
- 根據上面討論的,我們先將偶數位的部分畫上底線,並從第二碼開始到最後一碼。
4003600000000014
好,讓我們先將畫底線的數字乘 2:
1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2
這會給我們:
2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
現在,把得到的每一位數字在加總:
2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
現在把前一個總和(13)跟沒有乘 2 的剩餘數字再次加總:
13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20
太棒了,加總後的數字是(20),最後一碼的數字為 0,所以 David 的卡片是合格的!
驗證信用卡號並不難,但每次親自動手去計算也太累了。
我們透過寫程式來做這個。
實作細節
請在 credit
資料夾下有個叫 credit.c
的檔案,
撰寫會詢問用戶信用卡號,並回報(透過printf
)是否為合格的 美國運通,萬事達,Visa 卡號。
我們要求你的程式最後回傳的結果必須是AMEX\n
或 MASTERCARD\n
或 VISA\n
或 INVALID\n
,
所以我們可以自動化測試你的程式碼。
為了簡化,你可以假設用戶的輸入都是數字(沒有 -
,這類可能會印在實卡上的字),
還有不會出現 0 開頭的情況。
但不要假設用戶輸入只會符合 int
!
最好是使用 CS50 函式庫中的 get_long
來取得用戶輸入。
當拋入合格的信用卡號時,
請參考以下示範你的程式碼應該要具備的行為。
$ ./credit
Number: 4003600000000014
VISA
現在,get_long
會自動將 -
或其他不合格輸入忽略。
$ ./credit
Number: 4003-6000-0000-0014
Number: foo
Number: 4003600000000014
VISA
但是你要自行決定如何驗證不合規定的信用卡號(像是 電話號碼):
$ ./credit
Number: 6176292929
INVALID
用大把的輸入測試你的程式,合格跟不合格都要。
這邊有一些卡片號碼是 Paypal 建議的測資。
如果你的程式行為在某些輸入下結果不正確 (或是無法編譯),就是該除錯的時候了!
如何測試你的程式碼
你可以透過 check50
來執行下面的指令檢查你的程式是否正確,
但最好是先自己先試試是否能編譯跟測試!
check50 cs50/problems/2022/x/credit
透過 style50
執行下面的指令會檢查你的程式風格。
style50 credit.c
如何提交
在你的 terminal,輸入以下指令可以提交你的功課。
submit50 cs50/problems/2022/x/credit