微信扫一扫的扫码功能是本地实现还是联网实现的?

微信扫一扫的扫码功能很弱,速度慢,经常有二维码识别不了。Dynamsoft的同事怀疑微信的扫码不是在本地完成的,而是把数据传输到了server端来解码。如何才能得到答案?

微信扫一扫网速检测

为什么会有人怀疑微信的扫码是需要连接server的,原因在于在断网的情况下,微信扫描是不可用的。那么在联网的情况下怎么可以知道数据传输了没有?我在手机上打开状态栏网速显示。

微信扫一扫的扫码功能是本地实现还是联网实现的?

数值很小,不可能有图像数据传输。扫码应该是本地完成的。再进一步验证下。

窥探微信安装包

手机应用的安装包其实就是一个压缩包,用7zip解压,打开目录lib\armeabi。里面包涵了微信安卓应用所用到的C/C++动态链接库。

微信扫一扫的扫码功能是本地实现还是联网实现的?

大概扫一下,看到了libwechatQrMod.so,应该就是用于二维码的了。用atom打开,居然发现了这个:


微信扫一扫的扫码功能是本地实现还是联网实现的?

微信的1D/2D barcode解码居然用的是开源的ZXing!腾讯应该做了一些修改。

通过jadx反编译dex文件,可以看到有一个叫QbarNative的类:

package com.tencent.qbar;
import android.graphics.Bitmap;
import android.graphics.Point;
import com.tencent.mm.compatible.util.j;
import java.io.UnsupportedEncodingException;
public class QbarNative {
    public static byte[] data;
    public static byte[] jZG;
    public static byte[] jZH;
    public static int[] jZI;
    private static class a {
    }
    public static native int Encode(byte[] bArr, int[] iArr, String str, int i, int i2, String str2, int i3);
    private static native int EncodeBitmap(String str, Bitmap bitmap, int i, int i2, int i3, int i4, String str2, int i5);
    public static native int FocusInit(inti, int i2, boolean z, int i3, int i4);
    public static native boolean FocusPro(byte[] bArr, boolean z, boolean[] zArr);
    public static native int FocusRelease();
    private static native int GetOneResult(byte[] bArr, byte[] bArr2, byte[] bArr3, int[] iArr);
    private static native int GetResults(byte[] bArr, byte[] bArr2, byte[] bArr3, Point[] pointArr, int[] iArr, a aVar);
    public static native String GetVersion();
    public static native int Init(int i, int i2, int i3, String str, String str2);
    public static native int QIPUtilYUVCrop(byte[] bArr, byte[] bArr2, int i, int i2, int i3, int i4, int i5, int i6);
    public static native int Release();
    public static native int ScanImage(byte[] bArr, int i, int i2, int i3);
    public static native int SetReaders(int[] iArr, int i);
    public static native int focusedEngineForBankcardInit(int i, int i2, int i3, boolean z);
    public static native int focusedEngineGetVersion();
    public static native int focusedEngineProcess(byte[] bArr);
    public static native int focusedEngineRelease();
    private static native int nativeArrayConvert(int i, int i2, byte[] bArr, int[] iArr);
    private static native int nativeCropGray2(byte[] bArr, byte[] bArr2, int i, int i2, int i3);
    private static native int nativeGrayRotateCropSub(byte[] bArr, int i, int i2, int i3, int i4, int i5, int i6, byte[] bArr2, int[] iArr, int i7, int i8);
    public static native int nativeRelease();
    private static native int nativeTransBytes(int[] iArr, byte[] bArr, int i, int i2);
    private static native int nativeTransPixels(int[] iArr, byte[] bArr, int i, int i2);
    private static native int nativeYUVrotate(byte[] bArr, byte[] bArr2, int i, int i2);
    private static native int nativeYUVrotateLess(byte[] bArr, int i, int i2);
    private static native int nativeYuvToCropIntArray(byte[] bArr, int[] iArr, int i, int i2, int i3, int i4, int i5, int i6);
    static {
        jZG = new byte[100];
        data = new byte[3000];
        jZH = new byte[100];
        jZI = new int[4];
        j.a("wechatQrMod", QbarNative.class.getClassLoader());
    }
    public static int a(StringBuilder stringBuilder, StringBuilder stringBuilder2) {
        int GetOneResult = GetOneResult(jZG, data, jZH, jZI);
        try {
            String str = new String(jZH, 0, jZI[2], "UTF-8");
            if (str.equals("ANY")) {
                stringBuilder.append(new String(jZG, 0, jZI[0], "UTF-8"));
                stringBuilder2.append(new String(data, 0, jZI[1], "UTF-8"));
                if (stringBuilder2.length() == 0) {
                    stringBuilder.append(new String(jZG, 0, jZI[0], "ASCII"));
                    stringBuilder2.append(new String(data, 0, jZI[1], "ASCII"));
                }
            } else {
                stringBuilder.append(new String(jZG, 0, jZI[0], str));
                stringBuilder2.append(new String(data, 0, jZI[1], str));
            }
        } catch (UnsupportedEncodingException e) {
        }
        return GetOneResult;
    }
    public static int a(byte[] bArr, int[] iArr, byte[] bArr2, int i, int i2, int i3, int i4, int i5, int i6, int i7) {
        if (bArr == null || bArr2 == null) {
            return -1;
        }
        return nativeGrayRotateCropSub(bArr2, i, i2, i3, i4, i5, i6, bArr, iArr, i7, 0);
    }
    public static int a(byte[] bArr, byte[] bArr2, int i, int i2) {
        if (bArr2 == null) {
            return -1;
        }
        return nativeYUVrotate(bArr, bArr2, i, i2);
    }
    public static int a(byte[] bArr, byte[] bArr2, int i, int i2, int i3) {
        if (bArr == null || bArr2 == null) {
            return -1;
        }
        return nativeCropGray2(bArr, bArr2, i, i2, i3);
    }
    public static int a(byte[] bArr, int[] iArr, int i, int i2, int i3, int i4, int i5, int i6) {
        if (bArr == null) {
            return -1;
        }
        return nativeYuvToCropIntArray(bArr, iArr, i, i2, i3, i4, i5, i6);
    }
}

这下可以完全确认微信的扫码是在手机上完成的。

微信扫一扫的扫码功能是本地实现还是联网实现的?

上一篇:[转]Dcloud App离线本地存储方案


下一篇:【马哥linux学员学习笔记】zabbix实现微信报警