有没有一种简单的方法可以匹配字节数组中的字节数组?
Is there a simple method to match an array of bytes in an byte array?
我正在尝试检查字节数组中的字节序列。 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 Header 十六进制字符数组 here 的更多信息。
更新:
我刚才想我希望我可以使用正则表达式来找到我正在寻找的东西:
// dream code - find the value between those characters
var data:Object = byteArray.exec(/89,50,4E,47(.*?)0xF0,0xF1/);
当然,那只是梦。如果 ByteArrays 支持 RegEx,那就太容易了。
根据 Nick 的回答,我需要:
...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?
有什么方法可以帮我完成这部分吗?这就是我想知道的。这似乎是您必须经常做的事情,所以也许有功能。如果是这样的话,我可以 post 我到目前为止所写的内容。
PNG 和 JPG 都有指定的 header,并且它们都有特定的尺寸。您只需要读取 header 的字节(小心检查字节数组大小,以免超出范围)。对于 PNG,您首先检查是否有 4 个字节要读取,然后获取前 4 个字节,与 0x89、0x50、0x4E、0x47 序列进行比较。对于 JPG,前 3 个字节将为 0xFF 0xD8 0xFF。
另外请记住,AS3 加载程序 class 可以只获取其中任何一个的字节并为您计算出来。
我已将此方法放在一起,但它未能找到 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。不知道如何或为什么。我更新了函数以打印出十六进制字符和字符串字符,如果它转换为字符串(有时它是空的)。
看看这个例子是否对你有帮助。这个想法是找到一个候选字节,然后检查后续字节是否构成 rest-of-search 项。因此对于字节 CA FE BA BE
我们只搜索字节 0xCA
并且每当找到一个(从许多字节中)我们然后检查它是否跟随字节 0xFE
+0xBA
+0xBE
...
这是一个完整的学习计划...
你想要的主要功能是:
indexOfBytes (byteArray:ByteArray, value:String, startPosition:int = 0, endPosition:int = 0, endian:String = null):int
其中 return 是搜索序列开头偏移量的 int
。我输入了一个 checkImageFormat( bytes );
函数,其中 bytes
是 .jpg 或 .png 字节。这将 return 一个 String
表示是否 "jpg" 或 "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
我正在尝试检查字节数组中的字节序列。 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 Header 十六进制字符数组 here 的更多信息。
更新:
我刚才想我希望我可以使用正则表达式来找到我正在寻找的东西:
// dream code - find the value between those characters
var data:Object = byteArray.exec(/89,50,4E,47(.*?)0xF0,0xF1/);
当然,那只是梦。如果 ByteArrays 支持 RegEx,那就太容易了。
根据 Nick 的回答,我需要:
...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?
有什么方法可以帮我完成这部分吗?这就是我想知道的。这似乎是您必须经常做的事情,所以也许有功能。如果是这样的话,我可以 post 我到目前为止所写的内容。
PNG 和 JPG 都有指定的 header,并且它们都有特定的尺寸。您只需要读取 header 的字节(小心检查字节数组大小,以免超出范围)。对于 PNG,您首先检查是否有 4 个字节要读取,然后获取前 4 个字节,与 0x89、0x50、0x4E、0x47 序列进行比较。对于 JPG,前 3 个字节将为 0xFF 0xD8 0xFF。
另外请记住,AS3 加载程序 class 可以只获取其中任何一个的字节并为您计算出来。
我已将此方法放在一起,但它未能找到 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。不知道如何或为什么。我更新了函数以打印出十六进制字符和字符串字符,如果它转换为字符串(有时它是空的)。
看看这个例子是否对你有帮助。这个想法是找到一个候选字节,然后检查后续字节是否构成 rest-of-search 项。因此对于字节 CA FE BA BE
我们只搜索字节 0xCA
并且每当找到一个(从许多字节中)我们然后检查它是否跟随字节 0xFE
+0xBA
+0xBE
...
这是一个完整的学习计划...
你想要的主要功能是:
indexOfBytes (byteArray:ByteArray, value:String, startPosition:int = 0, endPosition:int = 0, endian:String = null):int
其中 return 是搜索序列开头偏移量的 int
。我输入了一个 checkImageFormat( bytes );
函数,其中 bytes
是 .jpg 或 .png 字节。这将 return 一个 String
表示是否 "jpg" 或 "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