Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PDF417使用Swift解码并生成相同的条形码_Swift_Barcode_Pdf417 - Fatal编程技术网

PDF417使用Swift解码并生成相同的条形码

PDF417使用Swift解码并生成相同的条形码,swift,barcode,pdf417,Swift,Barcode,Pdf417,我有以下PDF417条形码示例: 可以使用在线工具解码,如 结果如下:5wwwxww0app5p3pewi0edpeapifxe0iwwdfxxi0xf5e�¼ô���������CÌe%�æ‹�ÀsõbÿG)=x�qÀ1ß-�É�吕尼�Y[.H»Eáó¼ñü236²�tØتWp…Ã�{�Õ* 或 作为5wwwxww0app5p3peawi0peapifxe0iwwwfxxi0xf5e~| ~d~C`~e%~~~~到~B~{~dj9v~~Z[Xm~~“HP3~~~LH~~~O~”S~~,~~

我有以下PDF417条形码示例:

可以使用在线工具解码,如

结果如下:
5wwwxww0app5p3pewi0edpeapifxe0iwwdfxxi0xf5e�¼ô���������CÌe%�æ‹�ÀsõbÿG)=x�qÀ1ß-�É�吕尼�Y[.H»Eáó¼ñü236²�tØتWp…Ã�{�Õ*

作为
5wwwxww0app5p3peawi0peapifxe0iwwwfxxi0xf5e~| ~d~C`~e%~~~~到~B~{~dj9v~~Z[Xm~~“HP3~~~LH~~~O~”S~~,~~~~~k1~~u~Iw}SQ fqX4 mbc~
(我不知道这是用哪种编码方式编码的)

包含条形码的编码密钥的第一部分始终是已知的,它是
5wwwxww0app5p3pewi0edpeapifxe0iwwwfxxi0xf5e

它的第二部分可以从Base64字符串解码,它始终包含88个字节。在我的例子中,它是:

frz0daaaaaaaaaaararaijdymxljqdmiwhac/Vi/0cpyd4ghlxwdhflltgevmo+1b7GckT/OZ/svjosrpzwy5iu0xg87zl8fzsssg502l+qV3CFwxZ/ewjVKg=

我正在使用iOS设备上的Swift通过解码提供的base64字符串生成此PDF417条形码,如下所示:

let base64Str = "Frz0DAAAAAAAAAAArIJDYMxlJQDmiwHAc/Vi/0cpPYd4ghlxwDHflltGevmO+1b7GckT/OZ/sVJOSRpZWy5Iu0Xg87zl8fzssg502L+qV3CFwxZ/ewjVKg=="
let knownKey = "5wwwwwxwww0app5p3pewi0edpeapifxe0ixiwwdfxxi0xf5e"
let decodedData = Data(base64Encoded: base64Str.replacingOccurrences(of: "-", with: "+")
                                        .replacingOccurrences(of: "_", with: "/"))

var codeData=knownKey.data(using: String.Encoding.ascii)

codeData?.append(decodedData)
let image = generatePDF417Barcode(from: codeData!)
let imageView = UIImageView(image: image!)

//the function to generate PDF417 UIMAGE from parsed Data
func generatePDF417Barcode(from codeData: Data) -> UIImage? {

        if let filter = CIFilter(name: "CIPDF417BarcodeGenerator") {
            filter.setValue(codeData, forKey: "inputMessage")
            let transform = CGAffineTransform(scaleX: 3, y: 3)

            if let output = filter.outputImage?.transformed(by: transform) {
                return UIImage(ciImage: output)
            }
        }

        return nil
    }
但我总是得到错误的条形码生成。它可以被直观地看到

请帮助我更正代码,以获得与第一个条形码图像相同的结果

我还有另一个条形码示例:

密钥的第一部分是相同的,但它的第二部分被称为int8字节数组,我也不知道如何从中正确生成PDF417条形码(带前置密钥)

以下是我的尝试:

let knownKey = "5wwwwwxwww0app5p3pewi0edpeapifxe0ixiwwdfxxi0xf5e"
let secretArray: [Int8] = [22, 124, 24, 12, 0, 0, 0, 0, 0, 0, 0, 0, 100, 127, 67, 96, -52, 101, 37, 0, -85, -123, 1, -64, 111, -28, 66, -27, 123, -25, 100, 106, 57, 118, -4, 16, 90, 91, 88, 109, -105, 126, 34, 72, 80, 51, -116, 28, 76, 72, -37, -24, -93, 79, -115, 34, 83, 18, -61, 44, -12, -13, -8, -59, -107, -9, -128, 107, 49, -50, 126, 13, -59, 50, -24, -43, 127, 81, -85, 102, 113, 88, 52, -60, 109, 98, 99, 95] 
let secretUInt8 = secretArray.map { UInt8(bitPattern: $0) }
let secretData = Data(secretUInt8)


let keyArray: [UInt8] = Array(knownKey.utf8)
var keyData = Data(keyArray)

keyData.append(secretData)

let image = generatePDF417Barcode(from: keyData!)
let imageView = UIImageView(image: image!)

CIPDF417BarcodeGenerator
除了对生成的条形码外观有影响的
inputMessage
之外,还有一些输入参数-请参见。只有当您知道所有这些参数(最重要的是
inputCorrectionLevel
对于bo来说都是相等的时,对两个代码进行目视检查/比较才有意义th发电机

因此,与其进行视觉比较,不如尝试使用众多扫描仪应用程序中的一个对条形码进行解码,然后比较解码后的字节

对于第二个示例,请尝试以下方法:

// ...

var keyData = knownKey.data(using: .isoLatin1)!
keyData.append(secretData)

let image = generatePDF417Barcode(from: keyData)

这里发生了很多事情。Gereon有很多参数,这是正确的。选择不同的参数可能会导致解码完全相同的非常不同的条形码。您当前的条形码是“正确的”(尽管由于Apple bug有点凌乱)。这只是不同而已

我将从如何使您的数据与您拥有的条形码匹配的简短回答开始。然后我将介绍您实际应该做什么,最后我将详细说明原因

首先,这里是您要查找的代码(但可能不是您想要的代码,除非您必须匹配此条形码):


PDF 417定义了几种“压缩模式”,使其能够将真正令人印象深刻的信息打包到一个非常小的空间中,同时仍然提供出色的错误检测和更正,并处理许多现实世界中的扫描问题。默认压缩模式仅支持拉丁文本和基本标点符号。(如果只使用大写拉丁字母和空格,压缩效果会更好。)字符串的第一部分可以通过文本压缩存储,但其余部分不能,因此必须切换到字节压缩

默认情况下,Core Image的切换非常糟糕(我打开FB9032718进行跟踪)。它不是在文本中编码然后切换到字节,或者只是在字节中全部切换,而是不必要地一次又一次切换到字节

您无法配置多个压缩方法,但可以将其设置为byte,这就是值3。源代码也是这样做的

第二个区别是数据列的数量,这决定了输出的宽度。您的源代码使用5,但Core Image根据其默认规则选择6(这些规则没有完整的文档记录)

最后,您的源已将错误更正级别设置为0,这是不推荐的。对于此大小的邮件,建议的最小错误更正级别为3,这是Core Image默认选择的级别

如果您只是想要一个好的条形码,而不必匹配此输入,我的建议是将
inputCompactionMode
设置为3,其余为默认值。如果您想要不同的纵横比,我会使用
inputPreferredAspectRatio
而不是直接修改数据列的数量


你现在可能想停止阅读了。这是一个非常有趣的谜题,花了一上午的时间,所以我将在这里倾诉很多细节

如果你想深入了解这种格式的工作原理,我不知道目前除了的其他任何可用内容,这将花费你大约200美元。但GeoCities曾经有一些页面解释了很多这方面的内容,它们仍然可以通过网站获得

在命令行上也没有很多工具来解码这些东西,但是做得很好。我将使用它的输出来解释我是如何知道所有值的

您需要的最后一个工具是将jpeg输出转换为黑白pbm文件的方法,以便PDF417解码可以读取它们。为此,我使用以下方法(安装netpbm后):

接下来,让我们对现有条形码的前三行进行解码(旁边有我的注释)。在您看到的“函数输出”的地方,这意味着该值是某个函数的输出,该函数将另一个对象作为输入:

0 7f54 0x02030000 (0)    // Left marker
0 6a38 0x00000007 (7)    // Number of rows function output
0 218c 0x00000076 (118)  // Total number of non-error correcting codewords
0 0211 0x00000385 (901)  // Latch to Byte Compaction mode
0 68cf 0x00000059 (89)   // Data
0 18ec 0x0000021c (540)
0 02e7 0x00000330 (816)
0 753c 0x00000004 (4)    // Number of columns function output
0 7e8a 0x00030001 (1)    // Right marker

1 7f54 0x02030000 (0)    // Left marker
1 7520 0x00010002 (2)    // Security Level function output
1 704a 0x00010334 (820)  // Data
1 31f2 0x000101a7 (423)
1 507b 0x000100c9 (201)
1 5e5f 0x00010319 (793)
1 6cf3 0x00010176 (374)
1 7d47 0x00010007 (7)    // Number of rows function output
1 7e8a 0x00030001 (1)    // Right marker

2 7f54 0x02030000 (0)    // Left marker
2 6a7e 0x00020004 (4)    // Number of columns function output
2 0fb2 0x0002037a (890)  // Data
2 6dfa 0x000200d9 (217)
2 5b3e 0x000200bc (188)
2 3bbc 0x00020180 (384)
2 5e0b 0x00020268 (616)
2 29e0 0x00020002 (2)    // Security Level function output 
2 7e8a 0x00030001 (1)    // Right marker
接下来的3行将继续这种功能输出模式。请注意,相同的信息在左侧和右侧编码,但顺序不同。系统有很多冗余,可以检测到它看到的是条形码的镜像

为此,我们不关心行数,但给定当前行数
n
和总行数
n
,函数为:

30 * (n/3) + ((N-1)/3)
30 * (n/3) + 3*e + (N-1) % 3
=> 0 + 3*e + (23%3) = 2
=> 3*e + 2 = 2
=> 3*e = 0
=> e = 0
30 * (n/3) + (c - 1)
=> 0 + c - 1 = 4
=> c = 5
其中
/
al
30 * (n/3) + 3*e + (N-1) % 3
=> 0 + 3*e + (23%3) = 2
=> 3*e + 2 = 2
=> 3*e = 0
=> e = 0
30 * (n/3) + (c - 1)
=> 0 + c - 1 = 4
=> c = 5