场景分析:
1. app中使用手机号码获取验证码作为登录条件。(与各种电话平台合作,一般价格为 几分 - 1毛不等)
2. 电商app ,实名认证接口。 输入用户姓名与身份证号码进行实名认证 (一般公司都是与其他平台进行合作,基本上价格为 1次验证为1元左右)。
3. 电商app, 实时获取订单的物流信息, 输入物流号与物流公司,就可以获取到物流信息 (我们公司现在用的是快递100平台,分为了海外物流与国内物流 ,成本也是根据物流查询次数来计算价格。每天不超过2000次是免费的,但是超出的话,费用就相当贵了,不过对大公司来说,这个不算什么,也就包年20 - 30W,具体费用,可以与他们客服人员联系。)
4. 在线投票系统。 通过手机号码来进行投票。
解决办法:
针对以上问题。 以下是应对办法。
1. 手机号码登录 - 注册, 加上获取验证码间隔时间, 每一分钟只能获取一次。
2. 实名认证接口 - 需要由服务器端进行配合, 通过手机UUID - 或者是ip地址 - 用户id - 来进行每日次数限定
3. 手机号码投票系统 - 可以通过限定号码每日的最大发送数量
4. 还有一种,是比较常见的,就是通过输入验证码,进行防止机器人通过恶意操作进行频繁点击,也可以防止人为的故意点击。 这样就可以防止用户在查询订单的时候,循环点击查询订单物流信息,最大程度上的减少运营的成本。替公司减少开支。
下面是编码过程;
生成验证码的具体代码: swift版本验证码生成项目demo地址: https://github.com/zhonggaorong/GenerateCodeDemo
项目效果:
GenerateCodeView.swift
//
// GenerateCodeView.swift
// GenerateCodeDemo
//
// Created by 张国荣 on 16/8/12.
// Copyright © 2016年 BateOrganization. All rights reserved.
//
import UIKit
//extension String {
// subscript (r: Range<Int>) -> String {
// get {
// let subStart = advence(self.startIndex, r.startIndex, self.endIndex)
// let subEnd = advance(subStart, r.endIndex - r.startIndex, self.endIndex)
// return self.substringWithRange(Range(start: subStart, end: subEnd))
// }
// }
// func substring(from: Int) -> String {
// let end = countElements(self)
// return self[from..<end]
// }
// func substring(from: Int, length: Int) -> String {
// let end = from + length
// return self[from..<end]
// }
//}
class GenerateCodeView: UIView {
//随机产生颜色
var randomColor = (Float)(arc4random()%255)/100.0
// 验证码位数
var codeNumber:Int = 4
var codeString:String = ""
//随机验证码数据源
var dataArray:[String] = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 5.0
self.layer.masksToBounds = true
self.changeBgColor()
self.CreateGenerateCodeAction()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
//改变背景颜色
func changeBgColor() -> Void {
self.backgroundColor = self.generateColor()
}
// 随机验证码的view实现
func CreateGenerateCodeAction() -> Void {
codeString = ""
for _ in 0...codeNumber-1 {
var d = random()%dataArray.count-1
if (d <= 0) {
d = 0
}else if (d >= dataArray.count) {
d = dataArray.count - 1
}
print("---totalcount %d currentCount %d",dataArray.count, d)
codeString = codeString.stringByAppendingString(dataArray[d])
}
self.setNeedsDisplay()
}
// 随机颜色
func generateColor() -> UIColor {
return UIColor.init(colorLiteralRed: (Float)(arc4random()%256)/256.0, green: (Float)(arc4random()%256)/256.0, blue: (Float)(arc4random()%256)/256.0, alpha: 1.0)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.changeBgColor()
self.CreateGenerateCodeAction()
}
// 把随机码画上去
override func drawRect(rect: CGRect) {
if codeString.isEmpty {
return;
}
self.backgroundColor = self.generateColor()
let textString:String = codeString
let charSize = textString.substringToIndex(textString.startIndex).sizeWithAttributes([NSFontAttributeName : UIFont.systemFontOfSize(16)])
let width = rect.size.width/CGFloat(codeNumber) - charSize.width - 5;
let hight = rect.size.height - charSize.height;
var mypoint:CGPoint
// 计算每个字符
var point_x:CGFloat
var point_y:CGFloat
let intWidth = UInt32(Float(width))
let intHight = UInt32(Float(hight))
for i in 0...textString.characters.count-1 {
let c:CGFloat = CGFloat(i)
let myIn:Int = Int(i)
point_x = (CGFloat)(arc4random()%intWidth) + rect.size.width/(CGFloat)(textString.characters.count) * c
point_y = (CGFloat)(arc4random()%intHight)
mypoint = CGPointMake(point_x, point_y)
let charStr = textString[textString.startIndex.advancedBy(myIn)]
let bb:String = ""
let t = bb.stringByAppendingString(String(charStr))
t.drawAtPoint(mypoint,withAttributes:([NSFontAttributeName : UIFont.systemFontOfSize(16)]))
}
let context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, 1)
var px:CGFloat = 0.0
var py:CGFloat = 0.0
for _ in 0...5 {
CGContextSetStrokeColorWithColor(context, self.generateColor().CGColor)
px = CGFloat(arc4random()%UInt32(Float(rect.size.width)))
py = CGFloat(arc4random()%UInt32(Float(rect.size.height)))
CGContextMoveToPoint(context, px, py)
px = CGFloat(arc4random()%UInt32(Float(rect.size.width)))
py = CGFloat(arc4random()%UInt32(Float(rect.size.height)))
CGContextAddLineToPoint(context, px, py)
CGContextStrokePath(context)
}
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
*/
}
//
// ViewController.swift
// GenerateCodeDemo
//
// Created by 张国荣 on 16/8/12.
// Copyright © 2016年 BateOrganization. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var myCodeTextField: UITextField!
@IBOutlet weak var generateCodeView: GenerateCodeView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
generateCodeView.CreateGenerateCodeAction()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func testingAction(sender: AnyObject) {
if generateCodeView.codeString == myCodeTextField.text {
var alert = UIAlertView.init(title:"恭喜", message: "验证通过", delegate: nil, cancelButtonTitle: "确 认")
alert.show()
}else {
var alert = UIAlertView.init(title:"失望", message: "验证失败", delegate: nil, cancelButtonTitle: "确 认")
alert.show()
}
myCodeTextField.resignFirstResponder()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
}