我正在尝试检查字节数组中的字节序列。 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,那将太容易了。
根据尼克的回答,我需要:
...循环字节数组,抓取每个字节,如果有匹配保持 比较,直到我找到完整匹配或文件结束?
有没有一种方法能为我做这部分?这就是我想知道的。这似乎是你经常需要做的事情所以也许有功能。如果是这样的话,我可以发布我到目前为止所写的内容。
答案 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