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

extended ascii characters
what is character encoding
ascii name converter
ascii printable characters
utf-8 to ascii
ascii encryption
us-ascii encoding
what is encoding utf-8

I'm trying to write a .txt file with extended ASCII code, but I need to do it on 8-bit characters.

I'd love to get extended ASCII from Codepage 437, but I can live with Mac OS Roman. But as it's operation on numbers, it shouldn't make any difference.

When using Character(UnicodeScalar(unicodePosition)), it works well for 0 to 127. Each character is 8-bit. From 128th scalar up, they are not ASCII/macOS Roman and they're encoded on 16 bits.

So I can create an array of UInt8 with specific characters that I want to save to file.

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]

But I have no idea on how to save such a list to a file, and then display it as extendedASCII or macOS Roman encoding.

I need to operate on this numbers because I'm trying to implement Vigenre Cipher for extended ASCII alphabet (or macOS Roman) and I need the 8-bit input to be 8-bit output so the content of the file have exactly the same file size. I have to do it on 256 characters, hence I need extended ascii/macOS Roman.

I'd also need to read this kind of file back, so method for reading a textile encoded with extended ASCII would also be appreciated. I guess that's why there's String.Encoding.nonLossyASCII and not only .ascii?

Codepage 437 is available as CFStringEncodings.dosLatinUS and can be converted to a String.Encoding as in How to use Big5 encoding in Swift on iOS:

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

Now you can convert the bytes to a string and back:

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]
    }
}

Swift, decoding “iso-8859-5”, How to encode extended ASCII/macOS Roman (characters from 128 to 255) on 1 byte in Swift? I'm trying to write a .txt file with extended ASCII code, but I need� How to encode extended ASCII/macOS Roman (characters from 128 to 255) on 1 byte in Swift? 1. How to pass an BIG5 chinese characters in objective-c. 0.

The simple approach is to start with a String instance, convert it to Data using a specified encoding and then convert it the [UInt8] array:

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

Be carefule with your encryption. Most characters in the range between 0 and 31 cannot be represented in text. They might not occur in the original text. But they will appear in the encrypted text. If you don't avoid it, the result will be binary data that can no longer be converted to readable text.

How to convert ASCII to hex in Swift3?, In Swift 4, you can convert your ascii encoded string to data with string.data(using : .ascii) To convert the data to How to encode extended ASCII/macOS Roman ( characters from 128 to 255) on 1 byte in Swift? Encoding Now you can convert the bytes to a string and back: let bytes = Data([240, 236]) // CP437 to string: if let � ASCII characters 32 to 128 are common among most languages and character sets, while characters above ASCII 127 are different for almost every character set. In the USA, Windows systems use the Latin-1 character set by default while the Macintosh uses the Roman character set .

So my final solution looks like this:

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

ASCII Encoding: Beginners, Newbies….We've Got All Of The Info , Later, IBM created the Extended version of BCD called Extended Binary As computers to settle into an 8-bit (1-byte) structure, ASCII gradually turned because Unicode's first 128 characters are the same as ASCII, it is For example, one system used it to toggle between roman and italic printing styles. I'm not familiar with Mac systems, but it seems that the old (8-bit) "MAC OS Roman" set is not (unlike ISO-8859-1) a strict subset of the Unicode character set (i.e. where the 256 values map directly to the 256 code-points in group 0, plane 0, row 0 of Unicode).

Replace unicode characters online, Converts Unicode text (UTF8) or 8 bits extended ASCII into normal 7 While ASCII only uses one byte to represent each character, Unicode Swift's String and Character types provide a fast, from these languages may replace some of those in the 128–255 4MB, Mac OS X 10. copy the cell > 3. 1.4 Extended ASCII. Extended ASCII is also referred to as 8-bit ASCII. Realising the shortcomings of 7-bit code, an 8-bit version was standardised. This included the US-ASCII encoding as first 128 characters (0-127) and another 128 (128-255) were added. It was first used by IBM for their PCs.

NSString and Unicode � objc.io, The best-known character encoding is ASCII. ASCII And as soon as you're dealing with values that do not fit into one byte, the question of how these numbers� Extended ASCII (EASCII or high ASCII) character encodings are eight-bit or larger encodings that include the standard seven-bit ASCII characters, plus additional characters. . Using the term "extended ASCII" on its own is sometimes criticized, because it can be mistakenly interpreted to mean that the ASCII standard has been updated to include more than 128 characters or that the term

Unicode, UTF8 & Character Sets: The Ultimate Guide — Smashing , Let's say my computer used the number 1 for A, 2 for B, 3 for C, etc and yours However, unlike ASCII, characters 128-255 were never standardized, and various UTF-8 is therefore a multi-byte variable-width encoding. A character block with many names (Latin-1 Supplement, Unicode 128-255 block, Extended ASCII or ISO/IEC 8859), it sits right on top of the first 128 ASCII characters. Background - Learn a bit of the rocky history that followed the standardization of ASCII in the 1960s.

Comments
  • There's String.Encoding.macOSRoman. Why don't you use it?
  • Because in Vigenre Cipher I need to operate on numbers. To encrypt letter "a" (97) with key "b" (98) I will 97+98=196 get a symbol math function in macOS Roman. But I need to be able to create this character using this number, like this Character(macOSRomanSymbol(196))
  • Eh, that's irrelevant. You were asking about using encoding to/from strings. There's proper encoding .macOSRoman, use it instead of .ascii/.nonLossyASCII
  • WOW. I think this is it! I'll test it and come back with the results! :)
  • That worked well for saving bytes to file. How to load test.txt file encoded with 437 to array of 8UInt? Trying let data = NSData(contentsOfFile: "/Users/vol/Downloads/test.txt")! as Data
  • @vol: The counterpart to let string = String(data: bytes, encoding: encoding) is let bytes = string.data(using: encoding)
  • @vol: But note that you can read/write Data to/from a file without using strings or any encoding, perhaps that is what you actually need?
  • Thanks. I need that one because encryption key is a string taken from TextField, from GUI. You sir are the best!
  • In Vigenre Cipher I need to operate on numbers. To encrypt letter "a" (97) with key "b" (98) I will 97+98=196 get a symbol math function in macOS Roman. But I need to be able to create this character using this number, like this Character(macOSRomanSymbol(196)). In your solution I'd need to write the whole mapping from Unicode Numbers to macOS Roman numbers myself.
  • @vol: I don't understand where you get your numbers from. You should probably provide more information in your question. Anyway, you don't need to map it yourself. It's done in line 2 of my code. Let's say you start with an array of Unicode codepoints, then you can easily create a string with them and apply my code to get an array of MacOSRoman codes.
  • @vol: Or are you in fact looking for the reverse operation: MacOSRoman to Unicode?
  • The function saveToFile can be simplified. It converts binary data to a string and the back to binary data using the same encoding. There is no need to go via a string.
  • Can you show me a snippet on how to save Data object directly to a file as a binary data?
  • You can reduce the entire function to data.write(to: path).
  • which makes wrapping it in a separate method completely redundant. Awesome :D Thanks for the tip. You're 300% right!