有一个简单的方法来匹配字节数组中的字节数组吗? [英] Is there a simple method to match an array of bytes in an byte array?

查看:354
本文介绍了有一个简单的方法来匹配字节数组中的字节数组吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图检查一个字节数组中的字节序列。有没有在 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)}

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



有关十六进制字符的PNG标题数组的更多信息此处

更新:

我刚才以为我希望我可以使用正则表达式来找到我' m找的像这样:

$ pre $梦想代码找到这些字符之间的值
var data:Object = byteArray.exec(/ 89,50,4E,47(*)0xF0,0xF1 /?);

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



根据Nick的回答,我需要:

lockquote

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

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

。这个想法是找到一个候选字节,然后检查以下字节是否构成搜索余项。因此,对于字节 CA FE BA BE ,我们只搜索字节 0xCA ,只要找到一个(多个)然后检查它是否跟着字节 0xFE + 0xBA + 0xBE ...



这里有一个完整的程序来研究...


主要功能想要的是:
$ b $ pre $ lt; code> indexOfBytes(byteArray:ByteArray,value:String,startPosition:int = 0,endPosition:int = 0,endian :String = null):int

返回 int 搜索序列开始的偏移量。我已经引入了 checkImageFormat(bytes); 函数,其中 bytes .jpg .png 字节。这将返回一个字符串,表示是jpg还是png。

 
{

import flash.display.MovieClip;
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.utils。*;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLLoaderDataFormat;
导入flash.events。*;
导入flash.net.URLStream;


public class Check_Bytes_Image_v1 extends MovieClip
{
public var bytes:ByteArray = new ByteArray();
public var stream:URLStream = new URLStream();
public var loader:Loader = new Loader();

public var formatFound:Boolean = false;
public var str_Format:String =;
public var str_Search:String =;
public var tempStr:String =;
public var tempUInt:uint = 0;
public var bytePos:int = 0;

public var searchString:String =;;
public var searchArray:Array = new Array();

public function Check_Bytes_Image_v1()
{
//#add canvas
addChild(loader);

//#通过URLStream加载图像字节
stream.addEventListener(ProgressEvent.PROGRESS,onStreamProgress);
stream.addEventListener(Event.COMPLETE,completeHandler);
stream.load(new URLRequest(image1.png)); //image1.png


public function onStreamProgress(evt:ProgressEvent):void
{evt.target.readBytes(bytes,bytes.length,evt.target.bytesAvailable ); }

public function completeHandler(evt:Event):void
{

// bytes_toString(bytes); //如果要检查十六进制输出

//#更新格式为
的字符串str_Format = checkImageFormat(bytes);
trace(Image format is:+ str_Format);

searchString =89 50 4E 47; //在您的数组中使用任何已知的连续字节
bytePos = indexOfBytes(bytes,searchString);
trace(bytes begin at:+ bytePos);

bytes.position = 0; //重置为开始位置
loader.loadBytes(bytes); //解码&显示图像
trace(现在加载图像...);
//bytes.clear(); //清空字节
}

//#findBytes(byteArray:ByteArray,value:String,startPosition:int = 0,endPosition:int = 0,endian:String = null): int
public function indexOfBytes(byteArray:ByteArray,value:String,startPosition:int = 0,endPosition:int = 0,endian:String = null):int
{
str_Search = value;
trace(str_Search v1 is+ str_Search);
$ b $ //#清理可能的十六进制表示法
str_Search = str_Search.split(0x)。
str_Search = str_Search.split(。)。join();
str_Search = str_Search.split(/)。join();
$ b $ //#清理十六进制(删除非字母数字,空格,换行符等)
str_Search = str_Search.replace(/ \W + / g,); //清除所有非字母数字字符
str_Search.toUpperCase(); //#转换为大写
trace(str_Search v2 is+ str_Search);

tempUInt = 0; searchArray = []; //#重置

//#将输入字符串转换为每个插槽两位数组
while(tempUInt< str_Search.length)
{
searchArray .push(str_Search.substring(tempUInt,Math.min(tempUInt + 2,str_Search.length)));
tempUInt + = 2;


trace(searchArray length is:+ searchArray.length);
$ b $ //#搜索字节为相同的十六进制线索

//#为WHILE循环重置
if(startPosition!= 0){bytePos = startPosition; }
else {bytePos = 0; }

tempUInt = 0;

while(byteArray.bytesAvailable)
{
//#安全检查:停止在字节范围
if(endPosition!= 0)//#Don如果不为空,则不要结束pos
{
if(byteArray.position> = endPosition)
{
trace(到达搜索结束位置:停在: + byteArray.position);
break;


else //#不要超过字节长度
{
if(byteArray.position>(byteArray.length - searchArray.length ))
{
trace(达到ENDING搜索字节:停在:+ byteArray.position);
break;
}
} //#结束安全检查...

//#查找搜索值
byteArray.position = bytePos;
tempStr = byteToHex(byteArray.readUnsignedByte());
tempUInt = 0; //复位为TRUE计数

if(tempStr == searchArray [0])
{
//#tempUInt来计算真实的次数
/ /#如果总真的==搜索数组的长度然后我们发现匹配

// trace(----------------------- --------------------); (var i:int = 0; i< = searchArray.length-1; i ++)



bytePos = byteArray.position-1; (byteToHex(byteArray [bytePos + i])== searchArray [i])

// trace(bytes [+ bytePos +++ i + ]是:+ byteToHex(byteArray [bytePos + i]));
// trace(search array [+ i +]:+ searchArray [i]);
tempUInt ++; //#为两个数组的每个匹配条目添加+1
}

}

trace(tempUInt match is:+ tempUInt +|| Expected TRUE count:+ searchArray.length);

if(tempUInt == searchArray.length)
{
tempUInt = byteArray.position - 1;
trace(找到匹配找到的pos:+ tempUInt);
break;
}
else
{
tempUInt = int(-1);
trace(搜索时找不到匹配...当前pos:+(byteArray.position-1));
}

}

bytePos ++;

} //#结束WHILE循环

return tempUInt;


public function byteToHex(input:uint):String
{
tempStr = input.toString(16);
if(tempStr.length< 2){tempStr =0+ tempStr; } //#如果只填充1个字符,则为零填充

return tempStr.toUpperCase();

$ b $公共函数checkImageFormat(inputBA:ByteArray):String
{
//#如果你需要读取格式为
的特定的字节顺序, AS3中的/#默认是BIG ENDIAN类型
//inputBA.endian = Endian.LITTLE_ENDIAN;
//inputBA.endian = Endian.BIG_ENDIAN;

formatFound = false; bytePos = 0;

while(formatFound == false)// *继续直到BREAK动作
{
if(formatFound == true){trace(## Found format ... );打破; }

inputBA.position = bytePos; // *重置职位
tempUInt = inputBA.readUnsignedByte(); // * READ byte =检查字节值为Int
bytePos = inputBA.position; //更新Pos到由READ动作引起的新的偏移移动
$ b $ //#检查JPG(开始xFF xD8 xFF xE0)
if(tempUInt == 0xFF)
{
inputBA.position = bytePos-1; // *返回一个字节以在下一次检查中包含FF
tempUInt = inputBA.readUnsignedInt(); // *一次读取4个字节(期望FF-D8-FF-E0)
// trace(tempUInt check:+ tempUInt);
if(tempUInt == 0xFFD8FFE0)// *检查IF等于预期值
{
inputBA.position + = 2; //跳过2个字节提前到期望的JFIF
tempUInt = inputBA.readUnsignedInt(); // *现在检查接下来的4个字节
if(tempUInt == 0x4A464946)// * if expected JFIF(as hex)value
{
str_Format =jpg;
trace(找到JPG开头+ JFIF头...); formatFound = true;

$ b $ //检查JPG
$ b $ //检查PNG(开始x89 x50 x4E x47)
if(tempUInt == 0x89)
{
inputBA.position = bytePos-1; // *返回一个字节,在下一次检查中包含89
tempUInt = inputBA.readUnsignedInt(); // *一次读取4个字节(期望89-50-4E-47)
// trace(tempUInt check:+ tempUInt);
if(tempUInt == 0x89504E47)// *检查IF EQUAL为期望值
{
tempUInt = inputBA.readUnsignedInt(); // *现在检查接下来的4个字节
if(tempUInt == 0x0D0A1A0A)// *如果也是期望的值
{
inputBA.position + = 4; //跳过4个字节提前到期望的IHDR
tempUInt = inputBA.readUnsignedInt(); // *现在检查接下来的4个字节

if(tempUInt == 0x49484452)// * if expected IHDR(as hex)value
{
str_Format =png;
trace(找到PNG start + IHDR header ...); formatFound = true;


$ b} //#end检查PNG

//#增加Pos在While循环顶部的字节值检查
bytePos ++;

} //#结束WHILE循环

return str_Format;


public function bytes_toString(ba:ByteArray):String
{
// trace(checking args:+ args);
tempStr =; var str_Hex:String =; var len:uint = ba.length;
ba.position = 0; (var i:uint = 0; i< len; i ++)



tempStr = ba.readUnsignedByte()。toString(16);

if(tempStr.length< 2){tempStr =0+ tempStr; } //#如果只有1个字符,则为零填充
str_Hex + = tempStr;
}

return str_Hex.toUpperCase();


public function bytes_toInt(... args):int
{
var temp_conv_ba:ByteArray = new ByteArray();

for(var i:uint = 0; i< args.length; i ++)
{temp_conv_ba [i] = args [i]; }

var int_fromBytes:int = int(0x+ bytes_toString(temp_conv_ba));
返回int_fromBytes;
}

} //#end class
$ b $ // //结束包


I'm trying to check for a sequence of bytes in a byte array. Is there a method in the ByteArray class that works like indexOf()?

For example,

I'm trying to find out if a file is a PNG or JPG and so I want to check the byte array for that sequence of characters.

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") }

I don't know if the code above is correct but I keep running into this problem where I have to find an array of bytes in a byte array. So my question is is there a method for what I'm looking for?

More info on the PNG Header array of hexadecimal characters here.

Update:
I've just now thought that I wish I could use a RegEx to find what I'm looking for like this:

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

Of course, it is only a dream. It would be too easy if RegEx was supported in ByteArrays.

According to Nick's answer I need to:

...loop the byte array, grab each byte and if there's a match keep comparing until I either find the full match or the end of the file?

Is there a method that does this part for me? That's what I'm wondering. It seems like something you'd have to do quite often so maybe there are functions. I can post what I've written so far if that's the case.

解决方案

See if this example helps you. The idea is to find a candidate byte and then check if following bytes makes up rest-of-search item. So for bytes CA FE BA BE we search only for byte 0xCA and whenever one (out of many) is found we then check if it's followed by bytes 0xFE+0xBA+0xBE...

Here's a complete program to study...

The main function you want is :

indexOfBytes (byteArray:ByteArray, value:String, startPosition:int = 0, endPosition:int = 0, endian:String = null):int

Which returns an int of the offset of search sequence's beginning. I've thrown in a checkImageFormat( bytes ); function where bytes are either .jpg or .png bytes. This will return a String saying whether if "jpg" or "png".

package  
{

import flash.display.MovieClip;
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.utils.*;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLLoaderDataFormat;
import flash.events.*;
import flash.net.URLStream;


public class Check_Bytes_Image_v1 extends MovieClip 
{
    public var bytes    :ByteArray = new ByteArray();
    public var stream   :URLStream = new URLStream();
    public var loader   :Loader = new Loader();

    public var formatFound : Boolean = false;
    public var str_Format : String = "";
    public var str_Search : String = "";
    public var tempStr : String = "";
    public var tempUInt : uint = 0;
    public var bytePos : int = 0;

    public var searchString:String = "";;
    public var searchArray:Array = new Array();

    public function Check_Bytes_Image_v1() 
    {
        //# add canvas
        addChild(loader);

        //# load image bytes via URLStream
        stream.addEventListener(ProgressEvent.PROGRESS, onStreamProgress);
        stream.addEventListener(Event.COMPLETE, completeHandler);
        stream.load(new URLRequest("image1.png")); //image1.png
    }

    public function onStreamProgress(evt:ProgressEvent):void
    { evt.target.readBytes(bytes, bytes.length, evt.target.bytesAvailable); }

    public function completeHandler(evt:Event):void 
    {

        //bytes_toString(bytes); //if you want to check hex output

        //# update a string with format type
        str_Format = checkImageFormat( bytes );
        trace("Image format is  : " + str_Format );

        searchString = "89 50 4E 47"; //use any known sequential bytes in your Array
        bytePos = indexOfBytes( bytes, searchString );
        trace("bytes begin at : " + bytePos);

        bytes.position = 0; //reset to starting pos
        loader.loadBytes(bytes); //decode & display image
        trace("loaded image now...");
        //bytes.clear(); //empty the bytes
    }

    //# findBytes (byteArray:ByteArray, value:String, startPosition:int = 0, endPosition:int = 0, endian:String = null):int
    public function indexOfBytes (byteArray:ByteArray, value:String, startPosition:int = 0, endPosition:int = 0, endian:String = null):int
    {
        str_Search = value;
        trace("str_Search v1 is " + str_Search);

        //# Clean up possible hex notation
        str_Search = str_Search.split("0x").join("");
        str_Search = str_Search.split(".").join("");
        str_Search = str_Search.split("/").join("");

        //# Clean up hex (remove non Alpha-Numeric, white spaces, new line, etc)
        str_Search = str_Search.replace(/\W+/g, ""); //# clear all non Alpha-Numeric chars
        str_Search.toUpperCase(); //# convert to uppercase
        trace("str_Search v2 is " + str_Search);

        tempUInt = 0; searchArray = []; //# resets

        //# convert input string into two-digits-per-slot array
        while ( tempUInt < str_Search.length) 
        {
            searchArray.push(str_Search.substring(tempUInt, Math.min(tempUInt+2, str_Search.length) ) );
            tempUInt += 2;
        }

        trace("searchArray length is : " + searchArray.length);

        //# search bytes for same hex vlues

        //# Resets for WHILE loop
        if ( startPosition != 0) { bytePos = startPosition; }
        else { bytePos = 0; }

        tempUInt = 0;

        while (byteArray.bytesAvailable)
        {
            //# safety check :  Stop at limit of bytes range
            if ( endPosition != 0 ) //# Don't go over end pos if not null
            {   
                if ( byteArray.position >= endPosition )
                { 
                    trace("reached end position of search : stopping at: " + byteArray.position );
                    break;
                }
            }
            else //# Don't go over total bytes length
            {
                if ( byteArray.position > (byteArray.length - searchArray.length) )
                { 
                    trace("reached ENDing bytes of search : stopping at: " + byteArray.position );
                    break;
                }
            } //# end safety check...

            //# Find search values
            byteArray.position = bytePos;
            tempStr = byteToHex( byteArray.readUnsignedByte() );
            tempUInt = 0; //reset for TRUE count

            if ( tempStr == searchArray[0] )
            {
                //# tempUInt to count how many times it was true
                //# if total true's == search array length then we found match

                //trace("-------------------------------------------");

                for (var i:int = 0; i <= searchArray.length-1; i++) 
                {
                    bytePos = byteArray.position-1;

                    if ( byteToHex( byteArray[bytePos+i] ) == searchArray[i] )
                    {
                        //trace("bytes [" +bytePos+ " + " +i+ "] is : " +  byteToHex( byteArray[bytePos+i] ) );
                        //trace("search array [" +i+ "] is : " + searchArray[i] );
                        tempUInt++; //# add +1 for each matching entry for both arrays
                    }

                }

                trace("tempUInt match is : " + tempUInt + " || Expected TRUE count : " + searchArray.length );

                if ( tempUInt == searchArray.length ) 
                { 
                    tempUInt = byteArray.position - 1;
                    trace("match FOUND for search at pos : " + tempUInt); 
                    break; 
                }
                else 
                { 
                    tempUInt = int(-1); 
                    trace("match NOT found for search... current pos : " + ( byteArray.position-1) );
                }

            }

            bytePos++;

        } //# end WHILE loop

        return tempUInt;
    }

    public function byteToHex ( input:uint ) : String
    {
        tempStr = input.toString(16); 
        if(tempStr.length < 2) { tempStr = "0" + tempStr; } //# zero padding if 1 char only

        return tempStr.toUpperCase();
    }

    public function checkImageFormat ( inputBA : ByteArray ) : String
    {
        //# If you need to READ as specific Endianness of format
        //# default in AS3 is BIG ENDIAN type
        //inputBA.endian = Endian.LITTLE_ENDIAN;
        //inputBA.endian = Endian.BIG_ENDIAN;

        formatFound = false; bytePos = 0;

        while( formatFound == false) //* keep going until BREAK action
        {
            if ( formatFound == true ){ trace("## Found format..."); break; }

            inputBA.position = bytePos; //* reset positions 
            tempUInt = inputBA.readUnsignedByte(); //* READ byte = check byte value as Int
            bytePos = inputBA.position; //* update Pos to new offset move caused by READ action

            //# Check for JPG (begins xFF xD8 xFF xE0)
            if (tempUInt == 0xFF) 
            { 
                inputBA.position = bytePos-1; //* go back one byte to include FF in next check
                tempUInt = inputBA.readUnsignedInt(); //* READ 4 bytes at once (expect FF-D8-FF-E0)
                //trace ("tempUInt check : " + tempUInt);
                if (tempUInt == 0xFFD8FFE0 ) //* check IF EQUAL to expected value
                { 
                    inputBA.position += 2; //skip 2 bytes ahead to expected pos of JFIF
                    tempUInt = inputBA.readUnsignedInt(); //* now check next 4 bytes
                    if (tempUInt == 0x4A464946) //* if expected JFIF (as hex) value
                    {
                        str_Format = "jpg";
                        trace("found JPG start + JFIF header..."); formatFound = true;
                    }
                }
            } //# end Check for JPG

            //# Check for PNG (begins x89 x50 x4E x47)
            if (tempUInt == 0x89) 
            { 
                inputBA.position = bytePos-1; //* go back one byte to include 89 in next check
                tempUInt = inputBA.readUnsignedInt(); //* READ 4 bytes at once (expect 89-50-4E-47)
                //trace ("tempUInt check : " + tempUInt);
                if (tempUInt == 0x89504E47 ) //* check IF EQUAL to expected value
                { 
                    tempUInt = inputBA.readUnsignedInt(); //* now check next 4 bytes
                    if (tempUInt == 0x0D0A1A0A) //* if also expected value
                    {
                        inputBA.position += 4; //skip 4 bytes ahead to expected pos of IHDR
                        tempUInt = inputBA.readUnsignedInt(); //* now check next 4 bytes

                        if (tempUInt == 0x49484452) //* if expected IHDR (as hex) value
                        {
                            str_Format = "png";
                            trace("found PNG start + IHDR header..."); formatFound = true;
                        }
                    }
                }
            } //# end Check for PNG

            //# Increment Pos for next byte value checking at top of While loop
            bytePos++;

        } //# end WHILE loop

        return str_Format;
    }

    public function bytes_toString ( ba:ByteArray ) : String
    {
        //trace("checking args : " + args);
        tempStr = "";   var str_Hex:String = ""; var len:uint = ba.length;
        ba.position = 0;

        for (var i:uint = 0; i < len; i++) 
        {
            tempStr=ba.readUnsignedByte().toString(16); 

            if(tempStr.length<2) { tempStr="0"+tempStr; } //# zero-padding if 1 char only
            str_Hex += tempStr ;
        }

        return str_Hex.toUpperCase();
    }

    public function bytes_toInt( ...args ) : int
    {
        var temp_conv_ba : ByteArray = new ByteArray();

        for (var i:uint = 0; i < args.length; i++) 
        { temp_conv_ba[i] = args[i]; }

        var int_fromBytes:int = int("0x" + bytes_toString(temp_conv_ba) );
        return int_fromBytes;
    }

} //# end class

} //# end package 

这篇关于有一个简单的方法来匹配字节数组中的字节数组吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆