AMF解析(二)

 
double:在AS中大于int的都需要用double表示,当然也包含浮点型了。我们以10.123来举例,通过AS写入字节数组,10.123的字节={5,64,36,62,249,219,34,208,229},一共8个字节,第一个字节5当然是表示类型了。其实AMF里的double就一算法,我们直接上c++代码看吧。
byte byteArray[] = {5,64,36,62,249,219,34,208,229};
LONG64 value = 0;
for(int i = 0;i < 8;i ++)
value += ((LONG64)byteArray[position++] & 255) << (8 * (7 - i));
int s = (value >> 63) == 0 ? 1 : -1;
int e = (int)((value >> 52) & 0x7ffL);
LONG64 m =  (e == 0) ? (value & 0xfffffffffffffL) << 1 : (value & 0xfffffffffffffL) | 0x10000000000000L;
double ret = s * m * pow((double)2,e - 1075);
通过以上计算后,就得到我们的结果了。
 
string:接下来我们来看下字符串的解析,这个我们要着重来讲下。我们以"abcdefg"与"程序员"2个字符串为例。首先也通过as写入字节数组,得到字节数组。
1、"abcdefg"={6,15,97,98,99,100,101,102,103}
第一个字节6当然也是类型啦。接下来,肯定是字符串的长度了,不知道长度怎么知道字符串呢。利用昨天讲的解析int的方法,把字符串长度解析出来,就是len=15,这时候我们发现长度不对啊。是的,我们要将读到的int右移1位,15 / 2 = 7,这就是我们的长度。有些人可能会问,为什么要右移1位,那一位有什么用处呢?还记得我们之前讲过AMF格式很简洁,那为什么简洁呢,其实就在这里了。
AMF中,会将一个数据包中读到的string按顺序保存到一个列表中,记住,这个列表只保存string。以便再出现一样的字符串,可以直接从列表中读,不需要重复发送,这样,便可以减少发送的字节数了。比如
obj.name = "vigour";
obj.school = "vigour";
我们将这个obj通过socket发送,其实"vigour"这个字符串只是通过name发送了一次,那school怎么办?当然就是标记下"vigour"是第几个字符串发送的。这时候,我们便知道了那移掉的一位有什么用处了。假设我们读到的int是a
if((a & 1) == 0) 表示最后位如果是0,则表示该字符串前面已发送过,是第a / 2次发送的。
if((a & 1) == 1) 表示最后位如果是1,则表示该字符串是全新发送,长度 = a / 2
这时候,我们知道了长度是怎么读取的。接下来,就根据长度读取后面15 / 2 = 7位字节,利用ascii码转换成相应的字符就行了。
 
2、"程序员"={6,19,231,168,139,229,186,143,229,145,152}
我们上面分析了字符的发送,作为我们,当然还有如何发送中文字符。哎,由于计算机语言都使用英文字符,使得我们讲中文看中文的人屡屡吃亏,常常出现什么中文乱码。所以,国人努力,发明的计算机或计算机语言都使用中文的(E语言就不提了。。)。
言归正转,上面我们解析了英语字符,其实这边就比较容易了。前面长度都一样的算法,就是在利用ascii码转换的时候要加判断。因为,最开始,ascii码只有128位,故此处,若小于128就可认为是英文字符,可直接转换。那如果大于128咋办呢?这里判断是否大于128,是因为要将字节右移4位,看代码。
switch(c >> 4)
      {
            //ASCII码小于127
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
            {
            处理ascii码
              }
      case 12:
            case 13:
          {
                    if((count += 2) > len) break;
            char char2 = byteArray[count - 1];
            if((char2 & 192) != 128) break;
            chArr[chCount] = (wchar_t)((c & 31) << 6 | char2 & 63);
            break;
          }
      case 14:
            {
                if((count += 3) > len) break;
        char char2 = byteArray[count - 2];
        char char3 = byteArray[count - 1];
        if((char2 & 192) != 128 || (char3 & 192) != 128) break;
        chArr[chCount] = (wchar_t)((c & 15) << 12 | (char2 & 63) << 6 | (char3 & 63) << 0);
        break;
          }
      case 8:
            case 9:
            case 10:
            case 11:
            default:break;
其实这里我们有必要说下utf8这种编码,在AS中发送的编码格式都是utf8,所以,了解utf8有助于我们知道为什么AMF是这样编码字符串的,为什么要右移4位呢,不是3位,也不是2位。
utf8的编码规则很简单,使用1-4个字节来表示。2条规则:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,utf8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
我们来看下,1-4个字节编码规则的第一个字节。
1字节:0xxxxxxx,当第一位是0时,便表示这是单字节字符。
2字节:110xxxxx,当前2位是1的时候,便表示这是俩字节字符。
3字节:1110xxxx,当前3位是1的时候,便表示这是三字节字符。
4字节:11110xxx,当前4位是1的时候,便表示这是四字节字符。
所以,上面我们为什么要右移四位知道了吧。是为了判断是几字节字符,当是1字节时,0xxx最大表示7,最小为0。当是2字节时,110x范围是12-13。当是3字节时,1110便是14。因为只有极少数字符是使用4字节,所以AMF里不考虑4字节的。我们搞清楚utf8编码规则后,上面的代码便容易理解了。我们分析下双字节
if((count += 2) > len) break;            来判断下一字节是否有效
if((char2 & 192) != 128) break;        这个是来判断第二个字节是否以10开头
((c & 31) << 6 | char2 & 63);            这里是将第一字节的前三位与第二字节的前两位去掉并连接,因为我们讲过除了那几位,余下的才是unicode码,也就是我们需要的进制。
其实三字节的也是一样的道理,留给大家自己去解析吧,到这里,我们基本把string解析完了。
有点小累,剩下的,改天再打吧。如果有看不懂的,可能是我表达不清楚,大家可以自己试下,或者跟我讨论也行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PHP 解析 AMF(Action Message Format)可以使用 open-flash-remoting 扩展来实现。Open-flash-remoting 是一个用于 AMF 解析和处理的扩展,可以让 PHP 与 Flash 进行数据交互。 要解析 AMF 数据,首先需要安装 open-flash-remoting 扩展。可以通过以下步骤来完成安装: 1. 下载 open-flash-remoting 可执行程序(.dll 文件)对应的版本,确保与 PHP 的版本兼容。 2. 找到 PHP 安装目录下的 ext 文件夹,将下载的 .dll 文件复制到该文件夹中。 3. 打开 PHP 的配置文件(php.ini),找到并编辑以下行: ```ini ; Dynamic Extensions ; ... ; ... extension=php_open_flash remoting.dll ``` 4. 保存并关闭配置文件。 5. 重启 Web 服务器(例如 Apache)。 在成功安装了 open-flash-remoting 扩展后,就可以通过以下步骤来解析 AMF 数据: 1. 接收从 Flash 发送的 AMF 数据。 2. 使用 open-flash-remoting 扩展提供的函数,如 amf_decode(),来解析接收到的 AMF 数据。 3. 处理解析后的数据,根据数据类型和结构进行相应的操作,如存储到数据库、生成 HTML 内容等。 4. 将处理后的数据返回给 Flash 或其他需要的应用程序。 PHP 解析 AMF 数据的好处是,它可以实现更高效的数据交互,减少数据传输量和处理时间。AMF 是一种二进制格式,比起 XML 或 JSON 格式,AMF 的数据量更小,解析速度更快,适用于需要频繁传输大量数据的应用场景,如在线游戏、聊天应用等。 总之,通过安装 open-flash-remoting 扩展,我们可以在 PHP 中解析和处理 AMF 数据,实现高效的数据交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值