2015-02-19 9 views
2

Я пишу приложение командной строки для OS X в Swift. Мне нужно запросить имя пользователя и пароль (а не учетную запись пользователя на компьютере, а не учетные данные, сохраненные в цепочке ключей). Я могу запросить имя пользователя просто отлично:Как создать безопасное поле ввода пароля в приложении командной строки?

func getInput() -> String { 
    var keyboard = NSFileHandle.fileHandleWithStandardInput() 
    var inputData = keyboard.availableData 
    return NSString(data: inputData, encoding:NSUTF8StringEncoding)!.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) 
} 

let username = getInput() 

Я хотел бы ввести пароль, а также, но он выводит пароль в консоли, как пользователь вводит его. Как я могу принимать ввод от STDIN, не возвращая его обратно на консоль?

Обратите внимание: мне нужно, чтобы приложение было интерактивным, пользователь никогда не будет передавать имя пользователя и пароль в качестве аргументов командной строки, поэтому argv не является правильным ответом.

Например, если сделать это в Ruby, вы должны ввести это:

require 'io/console' 
puts "Enter your password" 
@password = STDIN.noecho(&:gets).chomp 

И тогда это отображение будет на экране, как это изображение:

Hidden password field example

Независимо от того, сколько буквы вводятся, он показывает только синий квадрат с точкой в ​​нем. Он не печатает пароль на экране, и он также не показывает ********* для пароля.

Можно ли сделать то же самое с Swift или Objective-C в командной строке приложения OS X?

ответ

3

Используйте функцию C getpass(3). Например:

char *p = getpass("Please enter your password: "); 
NSString *password = [NSString stringWithUTF8String:p]; 
NSLog(@"%@", password); 
7
inputString = String(validatingUTF8: UnsafePointer<CChar>(getpass("Please enter your password: "))) 

Это, как вы могли бы получить вход, используя быстрое

8

Просто для полноты картины: GetPass() отлично работает для паролей, но, к сожалению, эта функция также имеет ограничение что он может читать только до 128 символов. Если вы хотите запросить очень длинную парольную фразу или частные ключи, используйте вместо этого readpassphrase() BSD.

Swift 2.0 Пример:

let buf = [Int8](count: 8192, repeatedValue: 0) 
let passphrase = readpassphrase("Enter passphrase: ", (UnsafeMutablePointer<Int8>)(buf), buf.count, 0) 
if let passphraseStr = String.fromCString(passphrase) { 
    print(passphraseStr) 
} 

Swift 3.1 Пример:

let buf = [Int8](repeating: 0, count: 8192) 
if let passphrase = readpassphrase("Enter passphrase: ", (UnsafeMutablePointer<Int8>)(mutating: buf), buf.count, 0), 
    let passphraseStr = String.init(validatingUTF8: passphrase) { 

    print(passphraseStr) 
} 
Смежные вопросы