是否有一种简单的方法来匹配字节数组中的字节数组?

时间:2016-12-23 16:23:35

标签: javascript arrays regex actionscript-3 flash

我正在尝试检查字节数组中的字节序列。 ByteArray class中的方法是否与indexOf()类似?

例如,

我正在尝试查找文件是PNG还是JPG,因此我想检查该字符数组的字节数组。

var PNG_INFO:Array = [89,50,4E,47];
var byteArray:ByteArray = new ByteArray();

var position:int = byteArray.indexOf(PNG_INFO);
var value:String = byteArray.readBytes(position, PNG_INFO.length);

if (value =="PNG") { trace("is png") }

我不知道上面的代码是否正确但我一直遇到这个问题,我必须在字节数组中找到一个字节数组。所以我的问题是,我正在寻找一种方法吗?

有关十六进制字符here的PNG标头数组的详细信息。

更新
我刚才想到我希望我可以使用RegEx找到我想要的东西:

// dream code - find the value between those characters 
var data:Object = byteArray.exec(/89,50,4E,47(.*?)0xF0,0xF1/);

当然,这只是一个梦想。如果在ByteArrays中支持RegEx,那将太容易了。

根据尼克的回答,我需要:

  

...循环字节数组,抓取每个字节,如果有匹配保持   比较,直到我找到完整匹配或文件结束?

有没有一种方法能为我做这部分?这就是我想知道的。这似乎是你经常需要做的事情所以也许有功能。如果是这样的话,我可以发布我到目前为止所写的内容。

3 个答案:

答案 0 :(得分:4)

PNG和JPG都有一个指定的标题,它们都是特定的大小。您只需要读取标头的字节(小心检查字节数组大小,这样就不会超出范围)。在PNG的情况下,首先检查是否有4个字节要读取,然后获取前4个字节,与0x89,0x50,0x4E,0x47序列进行比较。对于JPG,前3个字节将是0xFF 0xD8 0xFF。

另外请记住,AS3 Loader类只能获取其中任何一个的字节并为您计算出来。

答案 1 :(得分:1)

我把这个方法组合在一起,但它找不到PNG数组中的第一个值,但是它找到的其他值也没问题。

var png:Array = [0x89,0x50,0x4E,0x47];
var pngIndex:int = getIndexOfValueInByteArray(byteArray, png, 0, 4);

/**
 * Gets the position where either a single character or an array of hexidecimal values are found in a byte array
 * */
public function getIndexOfValueInByteArray(byteArray:ByteArray, value:*, startPosition:int = 0, endPosition:int = 0, endian:String = null):int {
    var byte:uint;
    var byteString:String;
    var position:int;
    var matchIndex:int;
    var searchArray:Array;
    var searchByte:int;
    var searchByteString:String;
    var found:Boolean;
    var endOfFile:Boolean;
    var endIndex:uint;
    var debug:Boolean;
    var firstByte:uint;
    var firstByteString:String;
    var startIndex:uint;
    var searchArrayLength:int;
    var compareAsString:Boolean;

    debug = true;

    if (value is String) {
        searchArray = String(value).split("");
        compareAsString = true;
    }
    else {
        searchArray = ArrayUtil.toArray(value);
    }

    if (endian) {
        byteArray.endian = endian;
    }

    if (startPosition>-1) {
        byteArray.position = startPosition;
    }

    if (searchArray && searchArray.length) {
        firstByte = searchArray[0];
        firstByteString = compareAsString ? searchArray[0] : String.fromCharCode(firstByte);
        searchArrayLength = searchArray.length;
    }
    else {
        return -1;
    }

    while (byteArray.bytesAvailable) {
        byte = byteArray.readByte();

        if (!compareAsString && byte==firstByte) {
            debug ? trace("Byte:0x" + byte.toString(16) + " " + String.fromCharCode(byte)):void;

            for (var j:int = 1; j < searchArrayLength; j++) {
                byte = byteArray.readByte();
                searchByte = searchArray[j];

                debug ? trace("Byte:0x" + byte.toString(16) + " " + String.fromCharCode(byte)):void;

                if (byte==searchByte) {
                    if (j==searchArrayLength-1) {
                        found = true;
                        matchIndex = byteArray.position;
                        startIndex = matchIndex - searchArrayLength;
                        endIndex = matchIndex;

                        debug ? trace("Match found at " + startIndex):void;

                        break;
                    }
                }

                if (byteArray.bytesAvailable==0) {
                    endOfFile = true;
                    break;
                }
            }
        }

        else if (compareAsString && String.fromCharCode(byte)==firstByteString) {
            debug ? trace("Byte:0x" + byte.toString(16) + " " + String.fromCharCode(byte)):void;

            for (j = 1; j < searchArrayLength; j++) {
                byteString = String.fromCharCode(byteArray.readByte());
                searchByteString = searchArray[j];

                debug ? trace("Byte:0x" + byte.toString(16) + " " + searchByteString):void;

                if (byteString==searchByteString) {
                    if (j==searchArrayLength-1) {
                        found = true;
                        matchIndex = byteArray.position;
                        startIndex = matchIndex - searchArrayLength;
                        endIndex = matchIndex;

                        debug ? trace("Match found at " + startIndex):void;

                        break;
                    }
                }

                if (byteArray.bytesAvailable==0) {
                    endOfFile = true;
                    break;
                }
            }
        }
        else {
            debug ? trace("Byte:0x" + byte.toString(16) + " " + String.fromCharCode(byte)):void;
        }

        if (found || endOfFile || (endPosition!=0 && byteArray.position>endPosition)) {
            break;
        }
    }

    if (found) {
        debug?trace("Found at position " + startIndex + ". It ends at " + endIndex):0;
    }
    else {
        debug?trace("Could not find what the value you're looking for in this here byte array"):0;
        matchIndex = -1;
    }

    return matchIndex;
}

var png:Array = [0x89, 0x50, 0x4E, 0x47];
var pngIndex:int = getIndexOfValueInByteArray(byteArray, png, 0, 5);

追溯的值是:

Byte:0xffffff89
Byte:0x50
Byte:0x4e
Byte:0x47

如果我将byte设置为int而不是uint,则会打印出来:

Byte:0x-77
Byte:0x50
Byte:0x4e
Byte:0x47

当我使用JPEG并将byte设置为uint时,它会打印出此值:

var jpg:Array = [0xFF, 0xD8, 0xFF];
var jpgIndex:int = getIndexOfValueInByteArray(byteArray, jpg, 0, 5);

Byte:0xffffffff
Byte:0xffffffd8
Byte:0xffffffff
Byte:0xffffffe0

看起来它与最后一个值相匹配。

<强>更新
我只是传入0xFFFFFF89而不是0x89。这似乎适用于Mac。不知道如何或为什么。我更新了函数以打印出十六进制字符和字符串字符(如果它转换为字符串(有时它是空的))。

答案 2 :(得分:1)

看看这个例子是否对您有所帮助。我们的想法是找到一个候选字节,然后检查后续字节是否构成了其余的搜索项。因此,对于字节CA FE BA BE,我们仅搜索字节0xCA,每当找到一个(多个)时,我们检查它是否后跟字节0xFE + {{1} } + 0xBA ...

这是一个完整的学习课程......

您想要的主要功能是:

0xBE

返回搜索序列开头偏移量的indexOfBytes (byteArray:ByteArray, value:String, startPosition:int = 0, endPosition:int = 0, endian:String = null):int 。我已经在int函数中抛出checkImageFormat( bytes ); .jpg .png 字节。这将返回bytes,说明是否&#34; jpg&#34;或者&#34; png&#34;。

String