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

Javascript 是否有一种简单的方法来匹配字节数组中的字节数组?,javascript,arrays,regex,actionscript-3,flash,Javascript,Arrays,Regex,Actionscript 3,Flash,我试图检查字节数组中的字节序列。中是否有类似于indexOf()的方法 比如说, 我试图找出一个文件是a还是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

我试图检查字节数组中的字节序列。中是否有类似于
indexOf()
的方法

比如说,

我试图找出一个文件是a还是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") }
我不知道上面的代码是否正确,但我一直遇到这个问题,我必须在字节数组中找到一个字节数组。所以我的问题是,有没有一种方法可以满足我的需求

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

更新:
我刚才想,我希望我能用正则表达式找到我想要的东西,就像这样:

// dream code - find the value between those characters 
var data:Object = byteArray.exec(/89,50,4E,47(.*?)0xF0,0xF1/);
当然,这只是一个梦想。如果在ByteArray中支持正则表达式,那就太容易了

根据Nick的回答,我需要:

…循环字节数组,获取每个字节,如果有匹配项,则保留 在找到完全匹配或文件结尾之前进行比较


有没有一种方法可以帮我完成这个部分?这就是我想知道的。这似乎是你必须经常做的事情,所以可能有一些功能。如果是这样的话,我可以发布我目前为止写的东西

PNG和JPG都有一个指定的头,并且它们都有一个特定的大小。您只需要读取头的字节(小心检查字节数组大小,以免超出范围)。对于PNG,首先检查是否有4个字节要读取,然后获取前4个字节,并与0x89、0x50、0x4E、0x47序列进行比较。对于JPG,前3个字节将为0xFF 0xD8 0xFF


还请记住,AS3加载程序类可以只获取其中一个的字节,然后为您计算出来

PNG和JPG都有一个指定的头,并且它们都有一个特定的大小。您只需要读取头的字节(小心检查字节数组大小,以免超出范围)。对于PNG,首先检查是否有4个字节要读取,然后获取前4个字节,并与0x89、0x50、0x4E、0x47序列进行比较。对于JPG,前3个字节将为0xFF 0xD8 0xFF


还请记住,AS3加载程序类可以只获取其中一个的字节,然后为您计算出来

我把这个方法放在一起,但是它在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
设置为
int
而不是
uint
,它将打印出:

Byte:0x-77
Byte:0x50
Byte:0x4e
Byte:0x47
当我使用JPEG并将
字节设置为
uint
时,它会打印出以下值:

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

Byte:0xffffffff
Byte:0xffffffd8
Byte:0xffffffff
Byte:0xffffffe0
看起来它与最后一个值相匹配

更新:

我将只传入0xFFFF89而不是0x89。这在Mac上似乎有效。不知道如何或为什么。我更新了函数以打印出十六进制字符和字符串,如果它转换为字符串(有时为空)

我把这个方法放在一起,但是它在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
设置为
int
而不是
uint
,它将打印出:

Byte:0x-77
Byte:0x50
Byte:0x4e
Byte:0x47
当我使用JPEG并将
字节设置为
uint
时,它会打印出以下值:

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

Byte:0xffffffff
Byte:0xffffffd8
Byte:0xffffffff
Byte:0xffffffe0
看起来它与最后一个值相匹配

更新:

我将只传入0xFFFF89而不是0x89。这在Mac上似乎有效。不知道如何或为什么。我更新了函数以打印出十六进制字符和字符串,如果它转换为字符串(有时为空)

看看这个例子是否对你有帮助。其思想是找到一个候选字节,然后检查以下字节是否构成搜索项的其余部分。因此,对于字节
CA-FE-BA-BE
我们只搜索字节
0xCA
,只要找到一个(多个中的一个),我们就检查它后面是否跟字节
0xFE
+
0xBA
+
0xBE

这里有一个完整的学习计划…

您需要的主要功能是:

indexOfBytes (byteArray:ByteArray, value:String, startPosition:int = 0, endPosition:int = 0, endian:String = null):int
它返回搜索序列开头偏移量的
int
。我抛出了一个
checkImageFormat(字节)函数,其中
字节
.jpg.png字节。这将返回一个
字符串,说明是“jpg”还是“png”

包
{
导入flash.display.MovieClip;
导入flash.display.Sprite;
导入flash.utils.ByteArray;
导入flash.utils。*;
导入flash.display.Loader;
导入flash.net.URLRequest;
导入flash.net.URLLoaderDataFormat;
导入flash.events.*;
导入flash.net.URLStream;
公共类检查\u字节\u图像\u v1扩展MovieClip
{
公共变量字节:ByteArray=newbytearray();
公共变量流:URLStream=newurlstream();
公共变量加载器:加载器=新加载器();
找到公共变量formatFound:Boolean=false;
公共变量stru格式:String=“”;
公共变量stru_搜索:String=“”;
公共变量tempStr:String=“”;
公共变量tempUInt:uint=0;
公共变量bytePos:int=0;
public var searchString:String=“”;;
public var searchArray:Array=new Array();
公共函数检查\u字节\u图像\u v1()
{
//#添加画布
addChild(装入器);
//#通过URLStream加载图像字节
stream.addEventListener(ProgressEvent.PROGRESS、onStreamProgress);
stream.addEventListener(Event.COMPLETE,completeHandler);
stream.load(新的URLRequest(“image1.png”);//image1.png
}
过程中的公共功能(evt:ProgressEvent):无效
{evt.target.readBytes(bytes,bytes.length,evt.target.bytesAvailable);}
公共函数completeHandler(evt:事件):void
{
//bytes_toString(bytes);//如果要检查十六进制输出
//#使用格式类型更新字符串
str_Format=checkImageFormat(字节);
跟踪(“图像格式为:”+str_