草庐IT

android - Android 的 NSNonLossyASCIIStringEncoding 等价物

coder 2023-10-01 原文

我必须将一些聊天代码从 iOS 移植到 Android。在将聊天消息发送到套接字之前,iOS 代码使用 NSNonLossyASCIIStringEncoding 类作为 NSString::dataUsingEncoding 的参数。

在 Android 中你会怎么做?关于相反解码的相同问题。

如果不这样做,换行符就会在另一台手机收到的消息中消失。

iOS 上的代码:

NSData *data1 = [myStringTosend dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSString *goodValue = [[[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding] autorelease];

和解码:

NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];

到目前为止(不正确),Android 端的编码:

OutputStream os = socket.getOutputStream();
os.write(request.getBytes("UTF-8"));
os.flush();

和解码:

while ((bytesRead = is.read(buffer, 0, BUFFER_SIZE)) >= 0) {
    if (bytesRead > 0) response.append(new String(buffer, 0, bytesRead, "UTF-8"));
    if (bytesRead < BUFFER_SIZE) break;
}

最佳答案

@portforwardpodcast 是绝对正确的,如果可能的话,您应该避免对 utf8 进行 ASCII 编码,而是设置您的堆栈以直接处理/存储 utf8。也就是说,如果您没有能力更改行为,则以下代码可能会有所帮助。

虽然没有关于 NSNonLossyASCIIStringEncoding 工作原理的公开解释,但根据它的输出,它看起来像:

  • 扩展 ASCII 范围(十进制值 128 - 255)中的字节使用八进制编码进行转义(例如 ñ,十进制值为 241 -> \361)
  • 非 ASCII 代码点使用十六进制编码以两个字节 block 转义(例如?占用 32 位,十进制值为 128549 -> \ud83d\ude25)

所以编码:

public static String encodeToNonLossyAscii(String original) {
    Charset asciiCharset = Charset.forName("US-ASCII");
    if (asciiCharset.newEncoder().canEncode(original)) {
        return original;
    }
    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 0; i < original.length(); i++) {
        char c = original.charAt(i);
        if (c < 128) {
            stringBuffer.append(c);
        } else if (c < 256) {
            String octal = Integer.toOctalString(c);
            stringBuffer.append("\\");
            stringBuffer.append(octal);
        } else {
            String hex = Integer.toHexString(c);
            stringBuffer.append("\\u");
            stringBuffer.append(hex);
        }
    }
    return stringBuffer.toString();
}

然后解码(这可以通过在锁定步骤中解析两种类型的编码来提高效率,而不是作为两个单独的传递):

private static final Pattern UNICODE_HEX_PATTERN = Pattern.compile("\\\\u([0-9A-Fa-f]{4})");
private static final Pattern UNICODE_OCT_PATTERN = Pattern.compile("\\\\([0-7]{3})");

public static String decodeFromNonLossyAscii(String original) {
    Matcher matcher = UNICODE_HEX_PATTERN.matcher(original);
    StringBuffer charBuffer = new StringBuffer(original.length());
    while (matcher.find()) {
        String match = matcher.group(1);
        char unicodeChar = (char) Integer.parseInt(match, 16);
        matcher.appendReplacement(charBuffer, Character.toString(unicodeChar));
    }
    matcher.appendTail(charBuffer);
    String parsedUnicode = charBuffer.toString();

    matcher = UNICODE_OCT_PATTERN.matcher(parsedUnicode);
    charBuffer = new StringBuffer(parsedUnicode.length());
    while (matcher.find()) {
        String match = matcher.group(1);
        char unicodeChar = (char) Integer.parseInt(match, 8);
        matcher.appendReplacement(charBuffer, Character.toString(unicodeChar));
    }
    matcher.appendTail(charBuffer);
    return charBuffer.toString();
}

关于android - Android 的 NSNonLossyASCIIStringEncoding 等价物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13800183/

有关android - Android 的 NSNonLossyASCIIStringEncoding 等价物的更多相关文章

  1. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  2. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  3. java - Java 的 StringReader 的 Ruby 等价物是什么? - 2

    在Java中,可以像这样从一个字符串创建一个IO流:Readerr=newStringReader("mytext");我希望能够在Ruby中做同样的事情,这样我就可以获取一个字符串并将其视为一个IO流。 最佳答案 r=StringIO.new("mytext")和here'sthedocumentation. 关于java-Java的StringReader的Ruby等价物是什么?,我们在StackOverflow上找到一个类似的问题: https://st

  4. python - 什么是 Python 输出的 Ruby 等价物 [ :-1]? - 2

    在Python中,如果我想得到字符串的前n个字符减去最后一个字符,我会这样做:output='stackoverflow'printoutput[:-1]什么是Ruby等价物? 最佳答案 我不想太挑剔,但如果你想更像Python的方法,而不是做"StackOverflow"[0..-2]你可以做"StackOverflow"[0...-1]相同的结果。在Ruby中,带3个点的范围不包括正确的参数,而带两个点的范围包括它。因此,在字符串切片的情况下,三个点更接近Python的语法。 关于p

  5. ruby-on-rails - 为什么 do/end 和 {} 不总是等价的? - 2

    这个问题在这里已经有了答案:关闭11年前。PossibleDuplicate:RubyblockandunparenthesizedargumentsWhatisthedifferenceorvalueoftheseblockcodingstylesinRuby?我一直认为以下只是同一件事的两种表达方式:[1,2,3].collect{|i|i*2}[1,2,3].collectdo|i|i*2end但是我在我的一个ERB模板中发现了一些奇怪的行为,这两种语法似乎在做两件不同的事情。这段代码效果很好:m))}}%>但是当我将其重写为:m))endend%>...我最终得到了我的@men

  6. Java 有 FindBugs。 Ruby 的等价物是什么? - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:AutomaticcodequalitytoolforRuby?Java有FindBugs™。Ruby的等价物是什么?

  7. ruby - Ruby 中的 charCodeAt() 等价物 - 2

    我想知道是否存在与JavaScript的charCodeAt()方法等效的Ruby。charCodeAt()方法返回字符串中指定索引处字符的Unicode值。以下示例返回字符串中最后一个字符的Unicode值:str.charCodeAt("HELLOWORLD".length-1)#=>68在Ruby中有对应的吗? 最佳答案 您可以使用String#[]和String#ord方法:'HELLOWORLD'[-1].ord#=>68它还处理Unicode字符:'aā'[1].ord#=>257

  8. ruby - Tcl 是否具有 PE​​RL 和 Ruby backtic 的等价物 - 2

    在Ruby/PERL中,我可以很容易地将系统命令的控制台输出输入到一个文件中。例如:$k=`ls`将ls的输出输入到PERL(和Ruby)中的变量$k。如何在Tcl中做这样的事情?谢谢 最佳答案 使用exec命令得到相同的。setoutput[execls]puts$output手册页:exec 关于ruby-Tcl是否具有PE​​RL和Rubybacktic的等价物,我们在StackOverflow上找到一个类似的问题: https://stackoverf

  9. ruby - 是否有 Log4J for Ruby 的等价物,Log4Ruby? - 2

    找了一圈也没找到。是否有Ruby的Log4X等价物?如果不是,那么处理所有调试语句的最佳方法是什么。我是Ruby的新手。谢谢! 最佳答案 Ruby带有一个内置的日志库,但是有log4r.内置库的一个简短示例:#!/usr/bin/envrubyrequire'logger'log=Logger.new('mylog.txt')log.debug"Hellolog" 关于ruby-是否有Log4JforRuby的等价物,Log4Ruby?,我们在StackOverflow上找到一个类似的问

  10. objective-c - Ruby ||= Objective-C 中的等价物 - 2

    我最近一直在学习ruby​​,并且基本上爱上了||=特性,因为它可以使在ObjectiveC中编写惰性getter变得更加容易。目前我写的getter如下:-(NSArray*)myArray{if(!_myArray){_myArray=[NSArrayarray];}return_myArray}除非我遗漏了||=的某些内容,否则我将能够使用Ruby编写以前的代码:-(NSArray*)myArray{return_myArray||=[NSArrayarray];}那显然更干净了。Objective-C语言/运行时中是否有任何东西可以让您做到这一点?此外,以下是getter的单行

随机推荐