0

我正在尝试.txt使用扩展的 ASCII 代码编写文件,但我需要在 8 位字符上进行。

我很想从中获得扩展的 ASCII Codepage 437,但我可以忍受Mac OS Roman. 但由于它是对数字的操作,它不应该有任何区别。

使用时Character(UnicodeScalar(unicodePosition)),它适用于 0 到 127。每个字符为 8 位。从第 128 个标量开始,它们不是 ASCII/macOS Roman,它们以 16 位编码。

UInt8因此,我可以创建一个包含要保存到文件的特定字符的数组。

let firstCharacter: UInt8 = 240 // Apple Logo in macOS Roman or "≡" in codepage 437

let secondCharacter: UInt8 = 236 // Infinity symbol on codepage 437 or "I" with two dots in macOS Roman

let listOfCharacters: [UInt8] = [firstCharacter, secondCharacter]

但我不知道如何将这样的列表保存到文件中,然后将其显示为扩展 ASCII 或 macOS 罗马编码。

我需要对这些数字进行操作,因为我正在尝试为扩展的 ASCII 字母(或 macOS Roman)实现 Vigenre Cipher,并且我需要将 8 位输入作为 8 位输出,因此文件的内容具有完全相同的文件尺寸。我必须使用 256 个字符,因此我需要扩展 ascii/macOS Roman。

我还需要读回这种文件,因此读取用扩展 ASCII 编码的纺织品的方法也将不胜感激。我想这就是为什么有String.Encoding.nonLossyASCII而不是唯一的原因.ascii

4

3 回答 3

3

简单的方法是从一个String实例开始,将其转换为Data使用指定的编码,然后将其转换为[UInt8]数组:

let text = "The quick brown fox ... éâ..."
let data = text.data(using: .macOSRoman)
let characters [UInt8](data)

小心你的加密。0 到 31 范围内的大多数字符无法在文本中表示。它们可能不会出现在原始文本中。但它们会出现在加密文本中。如果不避免,结果将是无法再转换为可读文本的二进制数据。

于 2019-03-28T12:19:30.347 回答
3

代码页 437可用作CFStringEncodings.dosLatinUS并且可以转换String.Encoding如何在 iOS 上的 Swift 中使用 Big5 编码

let cfEnc = CFStringEncodings.dosLatinUS
let nsEnc = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(cfEnc.rawValue))
let encoding = String.Encoding(rawValue: nsEnc) // String.Encoding

现在您可以将字节转换为字符串并返回:

let bytes = Data([240, 236])
// CP437 to string:
if let string = String(data: bytes, encoding: encoding) {
    print(string) // ≡∞
    // String to CP437:
    if let bytes2 = string.data(using: encoding) {
        print(Array(bytes2)) // [240, 236]
    }
}
于 2019-03-28T12:23:13.883 回答
0

所以我的最终解决方案如下所示:

class FileManager {

    let encoding: String.Encoding

    init() {
        let cfEnc = CFStringEncodings.dosLatinUS
        let nsEnc = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(cfEnc.rawValue))
        let encoding = String.Encoding(rawValue: nsEnc)
        self.encoding = encoding
    }

    func loadFromFile(path: String) -> Data {
        return NSData(contentsOfFile: path)! as Data
    }

    func saveToFile(data: Data, path: String) {
        let string = dataToPage437String(data: data)
        let fileURL = URL(fileURLWithPath: path)
        try? string?.write(to: fileURL, atomically: false, encoding: encoding)
    }

    func page437StringToData(string: String) -> Data? {
         return string.data(using: encoding)
    }

    private func dataToPage437String(data: Data) -> String? {
        return String(data: data, encoding: encoding)
    }
}
class EncryptionEngine {

    func encrypt(originalData: Data, keyData: Data) -> Data {
        var encryptedData = [UInt8]()

        for (index, byte) in originalData.enumerated() {
            let indexInCurrentBlock = index % keyData.count
            let row = Int(byte)
            let column = Int(keyData[indexInCurrentBlock])
            //for pure Vigenère cipher modifier should be 0
            let modifier = index + 1
            let encryptedCharacter = UInt8((row + column + modifier) % 256)
            encryptedData.append(encryptedCharacter)
        }

        return Data(encryptedData)
    }
}
        let fileManager = FileManager()
        let encryptionEngine = EncryptionEngine()
        let originalData = fileManager.loadFromFile(path: "/Path/test2.txt")
        guard let keyData = fileManager.page437StringToData(string: "keyToEncryptTakenFromTextField") else { return }
        let encryptedData = encryptionEngine.encrypt(originalData: originalData, keyData: keyData)
        fileManager.saveToFile(data: encryptedData, path: "/Path/test_enc.txt")
于 2019-03-28T14:07:57.247 回答