【问题标题】:Using loops in python to configure credit card number在python中使用循环配置信用卡号
【发布时间】:2015-09-18 18:01:46
【问题描述】:

我正在做这个项目,我必须检查信用卡号是否有效。在这种情况下,我只需要一张 8 位数的信用卡(我知道这不是现实)。问题来了

信用卡号的最后一位是校验位,可防止抄录错误,例如一位数错误或两位数切换。以下方法用于验证实际的信用卡号,但为简单起见,我们将使用 8 位数字而不是 16 位来描述它:

• 从最右边的数字开始,形成所有其他数字的总和 数字。例如,如果信用卡号是4358 9795,那么您 形成总和5 + 7 + 8 + 3 = 23.

• 将前面未包含的每个数字加倍 步。添加结果数字的所有数字。例如,与 上面给出的数字,加倍数字,从 倒数第二个,yields 18 18 10 8。在这些值中添加所有数字 产生1 + 8 + 1 + 8 + 1 + 0 + 8 = 27

• 将前面两个步骤的总和相加。如果最后一位数字 结果为0,数字有效。在我们的例子中,23 + 27 = 50,所以 号码有效。

编写一个程序来实现这个算法。用户应提供一个 8 位数字,您应打印出该数字是否有效。如果它无效,则应打印使其有效的校验位的值。

我必须使用循环来求和。但是,我不知道如何使用循环。

这是我的代码

# Credit Card Number Check. The last digit of a credit card number is the check digit,
# which protects against transcription errors such as an error in a single digit or
# switching two digits. The following method is used to verify actual credit card
# numbers but, for simplicity, we will describe it for numbers with 8 digits instead
# of 16:
#     Starting from the rightmost digit, form the sum of every other digit. For
#     example, if the credit card number is 43589795, then you form the sum
#     5 + 7 + 8 + 3 = 23.
#    Double each of the digits that were not included in the preceding step. Add #    all
#     digits of the resulting numbers. For example, with the number given above,
#     doubling the digits, starting with the next-to-last one, yields 18 18 10 8. Adding
#     all digits in these values yields 1 + 8 + 1 + 8 + 1 + 0 + 8 = 27.
#     Add the sums of the two preceding steps. If the last digit of the result is 0, the
#     number is valid. In our case, 23 + 27 = 50, so the number is valid.
# Write a program that implements this algorithm. The user should supply an 8-digit
# number, and you should print out whether the number is valid or not. If it is not
# valid, you should print out the value of the check digit that would make the number
# valid.

    card_number = int(input("8-digit credit card number: "))

rights = 0
for i in card_number[1::2]:
   rights += int(i)

lefts = 0
for i in card_number[::2]:
   lefts += int(i)*2%10+int(i)*2/10

print card_number, (rights +lefts)/10

if remaining == 0:
    print("Card number is valid")

else:
    print("Card number is invalid")

    if digit_7 - remaining < 0:
        checkDigit = int(digit_7 + (10 - remaining))
        print("Check digit should have been:", checkDigit)

    else:
        checkDigit = int(digit_7 - remaining)
        print("Check digit should have been:", checkDigit)

【问题讨论】:

  • 你的错误是什么?
  • 没有错误,我需要为这个程序使用循环,不知道如何。这个程序有效,但它没有考虑交替数字和它们的双数的总和。总和的最后一位数字必须是 o。校验位为 4。
  • 您的问题是什么?目前尚不清楚您具体要寻求什么帮助。请编辑/更新您的问题以提出特定问题。
  • 丹,这是一个简单的问题。我们需要检查其有效性的 8 位信用卡号。条件是:- 1. 最后一位/校验位必须是 4。 2. 从最右边的数字开始,形成所有其他数字的总和。例如,如果信用卡号码是 4358 9795,那么你的和就是 5 + 7 + 8 + 3 = 23。现在把剩下的所有数字加倍。第一组数字和第二组数字之和应能被 10 整除。/或最后一位为 0。
  • 是的,但是您这样做有什么问题?

标签: python python-2.7 python-3.x


【解决方案1】:

如果我理解正确,您正在寻找这样的东西:

cards = ["43589795"]
for card_number in cards:  
     rights = sum(map(int, card_number[1::2]))
     lefts = sum(map(lambda x: int(x)*2%10+int(x)*2/10, card_number[::2])) # sum of doubled values
     print card_number, (rights +lefts)/10

没有地图和 lambda 魔法的相同解决方案:

rights = 0
for i in card_number[1::2]:
   rights += int(i)

lefts = 0
for i in card_number[::2]:
   lefts += int(i)*2%10+int(i)*2/10

print card_number, (rights +lefts)/10

完整回答您的问题:

card_number = str(raw_input("8-digit credit card number: ")).replace(" ", "")

rights = 0
for i in card_number[1::2]:
   rights += int(i)

lefts = 0
for i in card_number[::2]:
   lefts += int(i)*2%10+int(i)*2/10

remaining = (rights +lefts)%10

digit_7 = int(card_number[-1]) # Last digit

if remaining == 0:
    print("Card number is valid")

else:
    print("Card number is invalid")

    if digit_7 - remaining < 0:
        checkDigit = int(digit_7 + (10 - remaining))
        print("Check digit should have been:", checkDigit)

    else:
        checkDigit = int(digit_7 - remaining)
        print("Check digit should have been:", checkDigit)

【讨论】:

  • 是的,我是!你能在我的代码中即兴发挥吗?我会很感激的!
  • 什么意思?这正是你的算法。但不是number,我使用的是数字数组——卡片。映射它是for loop
  • 这里有一个问题。我们还不应该使用数组。所以从技术上讲,我们可以使用 for 和 while 循环,但不能使用 def 语句或数组。
  • 好的,@JoshShroeder,我创建了一个没有数组的版本。但是通过字符串符号进行迭代。我希望你没问题 :) 因为没有可迭代对象(字符串或数组/元组)就不可能进行迭代。
  • @Jmillian 你能检查我的编辑并更正我的代码吗?
【解决方案2】:

这是另一种可能的解决方案:

cc_number = input("8-digit credit card number: ").replace(" ", "")
total1 = 0
total2 = 0

for digit in cc_number[-1::-2]:
    total1 += int(digit)

for digit in cc_number[-2::-2]:
    total2 += sum(int(x) for x in str(int(digit)*2))

remainder = (total1 + total2) % 10

if remainder == 0:
    print("Card is valid!")
else:
    invalid_check_digit = int(cc_number[-1])

    if invalid_check_digit - remainder < 0:
        valid_check_digit = invalid_check_digit + (10 - remainder)
    else:
        valid_check_digit = invalid_check_digit - remainder

    print("Card is invalid - the correct check digit is {}".format(valid_check_digit))  

给你以下输出:

8-digit credit card number: 4358 9795
Card is valid!

或者:

8-digit credit card number: 4358 9794
Card is invalid - the correct check digit is 5

【讨论】:

  • 您好,马丁,感谢您的回答。如果卡号无效,我们如何找到正确的校验位?
【解决方案3】:

删除信用卡号中的所有空格并尝试以下代码:

import itertools
sum = 0
for multiplicand,didgit in zip(itertools.cycle([2,1]), str(CREDIT_CARD_NUMBER)):
    result = multiplicand * int(didgit)
    sum += result / 10
    sum += result % 10
print "valid" if sum % 10 == 0 else "invalid"

上述代码循环遍历信用卡号并同时计算两个总和。

【讨论】:

    【解决方案4】:

    这是使用numpy的解决方案:

    import numpy as np
    d1=np.transpose(np.array(list('43589795'), dtype=np.uint8).reshape((4,2)))[0]*2
    d2=np.transpose(np.array(list('43589795'), dtype=np.uint8).reshape((4,2)))[1]
    if (np.sum(np.hstack([list(entry) for entry in d1.astype(str)]).astype(np.uint8))+np.sum(d2))%10==0:
        return "Validated"
    

    在示例情况下,我们得到 50,这是经过验证的。

    【讨论】:

      猜你喜欢
      • 2021-01-13
      • 2015-08-25
      • 2016-01-22
      • 2013-12-08
      • 2020-06-28
      • 1970-01-01
      • 1970-01-01
      • 2017-01-09
      • 1970-01-01
      相关资源
      最近更新 更多