簡體   English   中英

如何在Swift中的1個字節上編碼擴展的ASCII / macOS Roman(字符從128到255)?

[英]How to encode extended ASCII/macOS Roman (characters from 128 to 255) on 1 byte in Swift?

我正在嘗試使用擴展的ASCII代碼編寫.txt文件,但是我需要對8位字符進行處理。

我很想從Codepage 437獲得擴展的ASCII,但是我可以使用Mac OS Roman 但是,因為它是對數字進行運算,所以不應該有任何區別。

使用Character(UnicodeScalar(unicodePosition)) ,它適用於0到127。每個字符均為8位。 從第128個標量開始,它們不是ASCII / macOS Roman,而是按16位編碼的。

因此,我可以創建一個UInt8數組, 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 Roman編碼。

我需要處理此數字,因為我正在嘗試為擴展的ASCII字母(或macOS Roman)實現Vigenre Cipher,並且我需要將8位輸入轉換為8位輸出,因此文件內容具有完全相同的文件尺寸。 必須使用256個字符,因此我需要擴展ascii / macOS Roman。

我還需要讀回這種文件,因此,讀取采用擴展ASCII編碼的紡織品的方法也將受到贊賞。 我猜這就是為什么會有String.Encoding.nonLossyASCII而不是.ascii嗎?

代碼頁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]
    }
}

一種簡單的方法是從String實例開始,使用指定的編碼將其轉換為Data ,然后將其轉換為[UInt8]數組:

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

請注意加密。 0到31之間的大多數字符不能用文本表示。 它們可能不會出現在原始文本中。 但是它們將出現在加密的文本中。 如果不避免,結果將是無法再轉換為可讀文本的二進制數據。

所以我的最終解決方案如下所示:

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")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM