2010年2月1日 星期一

2010/02/01 授權碼檢查

Nanosoft資訊軟體公司研發出一套商用軟體,準備於市面上販售,但唯恐遭到未經授權之不合法使用,因此在安裝軟體時,需要使用者輸入授權馬。試寫一個程式,其功能可以檢核此授權碼的正確信。
【規則敘述】
此授權碼由十個位數合成,每一位數可以為0~9的任何一個數字,是判斷方法如下:
首先,將此碼逐次的累加,使的第二位數成為第一位數到第二位數的和,第三位數為第一位數到第三位數的和....第十位數為第一位數到第十位數的和;
進行完第一次的累加和後 ,接著再將所得到的十個數字,第十個數字減掉第一個數字,第九個數字減掉第二個數字....以此類推,得到五組數字,將此五組數字由小到大排列後成為一個新的數列。
此新數列的後三碼為識別碼,必須可為11整除,方為正確的授權碼,故在螢幕上列印出"此為合法之授權碼",反之則印出"此為不合法之授權碼",若授權碼格式錯誤則顯示"授權碼格式錯誤"。

輸入範例:
請輸入授權碼:9476282354
輸出範例:
此為合法之授權碼

【提示】
輸入授權碼為9476282354
第一次運算後得到數列  9  13  20  26  28  36  38  41  46  50
第二次運算後得到數列  41  33  21  12  8
排序後得到數列引  812213341      (341被11整除)

出自  程式設計隊訓練教材  No.42  授權碼檢查

17 則留言:

  1. Dim a(10) As Integer
    Dim sum(5) As Integer
    Dim txt As String
    Dim ans As String
    Private Sub Form_Load()
    Open App.Path & "\in.txt" For Input As #1
    Input #1, n
    Close #1

    Open App.Path & "\out.txt" For Output As #2

    If Len(n) <> 10 Then
    ans = "授權碼格式錯誤"
    GoTo Error
    End If

    For i = 1 To 10
    x = Mid(n, i, 1)
    If x < "0" Or x > "9" Then
    ans = "授權碼格式錯誤"
    GoTo Error
    Else
    a(i) = a(i - 1) + x
    End If
    Next i

    For i = 1 To 5
    sum(i) = a(11 - i) - a(i)
    Next i

    For i = 1 To 5
    txt = sum(i) & txt
    Next i

    k = Val(Right(txt, 3))

    If k Mod 11 = 0 Then
    ans = "此為合法之授權碼"
    Else
    ans = "此為不合法之授權碼"
    End If
    Error:
    Print #2, ans
    Close #2
    End Sub

    回覆刪除
  2. 這題跟我們之前電腦軟體設丙級
    第1題檢察身分證字號是差不多的
    所以做起來有點複習的感覺@@

    回覆刪除
  3. Dim One(11), Two(6) As Integer
    Dim Three As String
    Private Sub Form_Load()
    Open App.Path & "/in.txt" For Input As #1
    Input #1, x
    Close #1
    Open App.Path & "/out.txt" For Output As #2
    t = Right(x, 10)
    For i = 1 To 10
    z = Mid(t, i, 1)
    If z < "0" Or z > "9" Then
    Print #2, "授權碼格式錯誤"
    Exit Sub
    End If
    One(i) = z + Val(One(i - 1))
    Next i
    For i = 1 To 5
    Two(i) = One(11 - i) - One(i)
    Three = Two(i) & Three
    Next i
    If Right(Three, 3) Mod 11 = 0 Then
    Print #2, "此為合法之授權碼"
    Else
    Print #2, "此為不合法之授權碼"
    End If
    Close #2
    End Sub
    真的很複習的FU...
    比想像中"甘丹"

    回覆刪除
  4. 高仔 你的程式是不是少判斷字串長度有沒有大於10??
    假如X是10個字以上 應該也是算格式錯誤(有錯請指教)

    回覆刪除
  5. Private Sub Form_Load()
    Dim a(10) As Integer
    Dim b(5) As Integer
    Open App.Path & "/in.txt" For Input As #1
    Input #1, x
    Close #1
    Open App.Path & "/out.txt" For Output As #2
    If Len(x) <> 10 Then
    Print #2, "授權碼格式錯誤"
    Else
    For i = 10 To 1 Step -1
    For j = 1 To i
    a(i) = a(i) + Mid(x, j, 1)
    Next j
    Next i
    Max = 1
    For i = 0 To 4
    b(i + 1) = a(10 - i) - a(i + 1)
    Next i
    ans = Right(b(2), 1) & b(1)
    If Val(ans) Mod 11 = 0 Then
    Print #2, "此為合法之授權碼"
    Else
    Print #2, "此為合法之授權碼"
    End If
    End If
    Close #2
    End Sub

    回覆刪除
  6. 上面有錯喔@@
    Private Sub Form_Load()
    Dim a(10) As Integer
    Dim b(5) As Integer
    Open App.Path & "/in.txt" For Input As #1
    Input #1, x
    Close #1
    Open App.Path & "/out.txt" For Output As #2
    If Len(x) <> 10 Then
    xx:
    Print #2, "授權碼格式錯誤"
    Else
    For i = 10 To 1 Step -1
    For j = 1 To i
    a(i) = Mid(x, j, 1)
    If x < "0" Or x > "9" Then GoTo xx
    Next j
    Next i
    Max = 1
    For i = 0 To 4
    b(i + 1) = a(10 - i) - a(i + 1)
    Next i
    ans = Right(b(2), 1) & b(1)
    If Val(ans) Mod 11 = 0 Then
    Print #2, "此為合法之授權碼"
    Else
    Print #2, "此為合法之授權碼"
    End If
    End If
    Close #2
    End Sub

    回覆刪除
  7. 上面Max = 1 多打的@@

    回覆刪除
  8. 阿瑋好,
    1.這題的重點就在,「了解題目複雜的說明」。
    而你就少看了一點,「由小到大排列」。
    所以你最後的接成一個字串,你只是接,沒有排序。
    要小心。
    2.你的累加的做法,很好。(高仔的也是一樣的好)
    3.去看看別人的程式,了解,並找出對錯點,很好。

    高仔好,
    1.像阿瑋說的,十個字長,也是要判斷的。
    2.和阿瑋一樣,你也少了「排序」。
    3.將字串直接去mod,也不是好的方式,阿瑋的val方式比較好。

    Y揚好,
    1.你的累加的方式,正確,但是,可以學阿瑋和高仔的方式,更好些。
    2.雖然改了max=1 但是,你們三個錯了同樣的地方吧。

    (還是我看錯了題目?)

    回覆刪除
  9. 老師
    這題應該可以不用排序
    因為阿@@越往後面+數越大
    所以a(10)-a(1) 一定會大於 a(9)-a(2) 大的
    因此把它倒過來就好@@(有錯請指導@@)

    回覆刪除
  10. 阿瑋好,
    這點倒是我沒想到,你對了九成九。
    你的程式和高仔的程式都對了,
    那至少Y揚的程式還是錯了。
    例如輸入為:
    1000010000
    ->
    1111122222
    ->
    11111
    也可能是等於。
    而且,差只有一個數字。

    回覆刪除
  11. 早上起來新雪從天空飄了下來,...(扯遠了)
    想到這個題目的第一個字,
    nanosoft原本應該只是想對應microsoft
    micro是微小
    nano是奈小
    出題者只是想開個冷笑話,但是
    http://nanosofttek.com/about_us.php
    請看,人家nanosoft是真有其公司的。
    所以,下次還是要甘願些,用個「某」公司,就好了。

    回覆刪除
  12. 大改了一下
    Private Sub Form_Load()
    Dim a(10) As Integer
    Dim b(5) As Integer
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Input #1, x
    Close #1
    If Len(x) <> 10 Then
    xx:
    Print #2, "授權碼格式錯誤"
    Else
    For i = 1 To 10
    If Mid(x, i, 1) < "0" Or Mid(x, i, 1) > "9" Then GoTo xx
    For j = 1 To i
    a(i) = a(i) + Mid(x, j, 1)
    Next j
    Next i
    For i = 4 To 0 Step -1
    b(i + 1) = a(10 - i) - a(i + 1)
    ans = ans & b(i + 1)
    Next i
    ans = Val(Right(ans, 3))
    If Val(ans) Mod 11 = 0 Then
    Print #2, "此為合法之授權碼"
    Else
    Print #2, "此為不合法之授權碼"
    End If
    End If
    End Sub

    回覆刪除
  13. Y揚好,
    1.修改是軟體避免不了的問題。(小程式可能除外)(軟體的更新和出新版,也是賺錢的方式之一)
    「知錯能改,善莫大焉」。(笑)
    2.你程式中的
    goto xx
    是跑到前面去,而且是在if...then...else...endif的中間。這會有問題吧?
    3.另外,用goto是速度快的方式,但是,是不結構化的方式。
    不結構化的話,很容易出了錯而不易找。
    以後的程式習慣中,要盡量減少。
    4.取代的方式,用旗子。
    iflag=false
    if mid(x,i,1)<"0" or mid(x,i,1)>"9" then iflag=true
    然後再exit for 去跳出迴圈,再用一個if去解決如果旗子為真的話。

    回覆刪除
  14. Dim aa(10) As Integer
    Dim bb(5) As Integer

    Private Sub Form_Load()
    Open App.Path & "/in.txt" For Input As #1
    Input #1, X
    sp = Split(X, ":")
    y = sp(1)
    For i = 1 To 10
    aa(i) = Mid(y, i, 1)
    Next i
    For i = 1 To 10
    aa(i) = aa(i - 1) + aa(i)
    Next i
    MaxA = 10
    For i = 1 To 5
    bb(i) = aa(MaxA - i + 1) - aa(i)
    Next i
    las = Mid(bb(2), 1, 1) * 100 + bb(1)
    ans = False
    If las Mod 11 = 0 Then
    ans = True
    End If
    Close #1
    Open App.Path & "/out.txt" For Output As #2
    If ans = True Then
    Print #2, "此為合法之授權碼"
    Else
    Print #2, "此為不合法之授權碼"
    End If
    Close #2
    End Sub

    Public Sub change(a, b)
    c = a
    a = b
    b = c
    End Sub

    回覆刪除
  15. 小白好,
    程式ok, 下一段程式寫得很好:
    For i = 1 To 10
    aa(i) = aa(i - 1) + aa(i)
    Next i

    回覆刪除
  16. Dim a(1000) As Long
    Dim x As String
    Public Sub Form_Load()
    Me.Hide
    Open App.Path & "/in.txt" For Input As #1
    Open App.Path & "/out.txt" For Output As #2
    Input #1, x
    For i = 1 To Len(x)
    a(i) = a(i - 1) + Val(Mid(x, i, 1))
    Next i
    For i = 1 To 5
    a(i) = Abs(a(i) - a(10 - i + 1))
    Next i
    For i = 1 To 5
    For j = i + 1 To 5
    If a(i) > a(j) Then bb = a(i): a(i) = a(j): a(j) = bb
    Next j
    Next i
    x = ""
    For i = 1 To 5
    x = x & a(i)
    Next i
    If Val(Right(x, 3)) Mod 11 = 0 Then
    Print #2, "此為合法之授權碼"
    Else
    Print #2, "此為不合法之授權碼"
    End If
    Close #1
    Close #2
    End
    End Sub

    8分59秒

    回覆刪除
  17. 再回頭看以前的程式,才會發現這時間的進步,很好。
    熊掌

    回覆刪除