Swift 中的 Base64 编码不会在 Android 中解码

Posted

技术标签:

【中文标题】Swift 中的 Base64 编码不会在 Android 中解码【英文标题】:Base64 encoding in Swift will not decode in Android 【发布时间】:2015-11-11 23:41:25 【问题描述】:

我有一个 android 应用程序,它使用 Base64 对图像进行编码,并且编码的字符串存储在服务器上。我现在正在为同一个应用程序制作一个 ios 客户端,并且正在努力让它以相同的方式对图像进行编码 在 android 端编码的图像将在 Swift iOS 中解码,但在 Swift 中编码的图像不会在 Android 中解码,或者这里http://www.freeformatter.com/base64-encoder.html(生成的文件不是有效的图像)

在 iOS 中编码的图像将在 iOS 中解码

在 Android 中,我使用以下代码进行编码和解码

public static String encodeBitmap(Bitmap bitmap) 
    Bitmap immagex = bitmap;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    immagex.compress(Bitmap.CompressFormat.PNG, 100, baos);
    byte[] b = baos.toByteArray();
    String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);
    return imageEncoded;


public static Bitmap decodeBitmap(String encodedString) 
    byte[] decodedByte = Base64.decode(encodedString, Base64.DEFAULT);
    Bitmap b = BitmapFactory.decodeByteArray(decodedByte, 0,
            decodedByte.length);
    return b;

iOS 端如下

static func decodeImage(str: String) -> UIImage?
    if let decodedData = NSData(base64EncodedString: str, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)
        var iconValue:UIImage? = UIImage(data: decodedData)
        return iconValue
    
    return nil


static func encodeImage(image: UIImage) -> String
    var imageData = UIImagePNGRepresentation(image)
    let base64 = imageData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding76CharacterLineLength)
    return base64

我愿意更改任一客户端以使其正常工作

示例: 以这张图片为例 https://pbs.twimg.com/profile_images/522909800191901697/FHCGSQg0.png

在 Android 上,它编码为 http://pastebin.com/D41Ldjis

在 iOS 上发送至http://pastebin.com/fEUZSJvF

iOS 的字符数要多得多

【问题讨论】:

我用 swift 看到的每个例子都显示了这个imageData.base64EncodedStringWithOptions(.allZeros) @tyczj 我也试过了,我试过 76 因为我注意到 android 生成的字符串每第 76 个字符就有新行 添加示例,数据十六进制转储和 Base64 字符串。你有没有在视觉上比较过它们?长度一样吗?它们在传输时是否经过 URL 编码? @zaph 好的。什么是十六进制转储?从视觉上看,它们完全不同。在转移之前,我从 println 的输出中检查了视觉相似性。我现在添加示例 @HamzahMalik 我认为您需要更新您的问题,因为问题在于您发送到 base64 编码器的 PNG 二进制数据 【参考方案1】:

所避免的 Base64 来自不同的 PNG 编码。标头不同,Android 有一个“sBIT”块,iOS 有一个“sRGB”块。

因此问题不在于 Base64,而在于这两个系统提供的表示。

解码部分

安卓: âPNG

IHDR††≠zsBIT€·O‡ÑIDAT

iOS: âPNG

IHDR»»≠XÆûsRGBÆŒÈiDOTd(ddp`ùıºIDAT

【讨论】:

我将如何解决这个问题?有没有办法强制一个人使​​用另一个人的编码? @zaph 更好地提供十六进制值而不是 ascii 其实这正是我想要呈现的,我唯一感兴趣的是 ASCII 中的块标签:PNG、IHDR、sBIT、sRGB 和 IDAT。 注意:Android Base64 解码生成想要的图像,iOS 版本没有。 我不明白你最后的评论。肯定是“故障”在 iOS 编码中?

以上是关于Swift 中的 Base64 编码不会在 Android 中解码的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 3 中从 Base64 编码的字符串创建图像? [复制]

用于上传的 Swift 3 base64 编码图像

如何在 Swift 3 中将 captureStillImageAsynchronously(sampleBuffer) 转换为 base64 编码

Swift Decodable - 如何解码经过 base64 编码的嵌套 JSON

如何将 protobuf 对象转换为 ByteArray 并在 Swift 中使用 Base64 URL_SAFE 进行编码?

将base64URL解码为base64 - Swift