多数大学生出来选择的工作和专业无关
首页 > 专业知识

PHP实现基于文本的莫斯电码生成器

时间:2018-02-22 17:28:27 [来源]:郑州PHP培训学校

   PHP实现基于文本的莫斯电码生成器

  文本莫斯代码生成器目前看起来还不错。当然,我们还可以对它做很多的修改和完善,比如使用其他字符集、直接从文件中读取文本、生成压缩音频等等。因为我们这个项目的目的是使其能够在网络上方便的使用,所以我们这个简单的方案,已经达到我们的目的了。
  下载源代码 – 2.63 KB
  PHP内核探索之PHP中的哈希表
  因为我希望通过web的方式访问我的摩斯代码音频文件,所以我决定采用PHP作为我主要的编程语言。上面的截图显示了一个开始生成莫斯代码的网页。在下载的zip文件中,包含了用于提交文本的网页以及用于生成和展现音频文件的PHP源文件。如果你想测试PHP代码,你需要将网页和相关的PHP文件复制到启用了PHP的服务器上。
  对于许多人来说,莫斯代码就像一些老电影中表现的那样,就是一些“点”和“横线”的序列,或者一连串的哔哔声。显然,如果你想用计算机代码来生成莫斯代码,这样的了解是远远不够的。这篇文章将会介绍生成莫斯代码的要素,如何生成WAVE 格式的音频文件,以及如何用PHP将莫斯代码转化成音频文件。
  莫斯代码
  莫斯代码是一种文本编码方式。它的优点是编码方便,而且用人耳就能够方便的解码。本质上,是通过音频(或者无线电频)的开和关,从而形成或短或长的音频脉冲,一般称作点(dot)和线(dash),或者用无线电术语称作“嘀”和“嗒”。用现代数字通信术语,莫斯代码是一种振幅键控(amplitude shift keying ,ASK)。
  在莫斯代码中,字符(字母,数字,标点符号和特殊符号)被编码成一个“嘀”和“嗒”的序列。所以为了把文本转化成莫斯代码,我们首先要确定如何来表示“嘀”和“嗒”。一个很显然的选择就是,用0表示“嘀”,用1表示“嗒”,或者反过来。不幸的是,莫斯代码采用的是可变长编码方案。所以我们也必须要使用一种可变长序列,或者采取一种方式,把数据打包成一种计算机内存通用的固定位宽(fixed bit-size)的格式。另外,需要特别注意的是,莫斯代码并不区分字母大小写,而且对一些特殊符号无法编码。在我们这个实现中,未定义的字符和符号将会被忽略。
  在这个项目中,内存占用并不是一个需要特别考虑的问题。所以,我们提出一个简单的编码方案,即用“0”来表示每个“嘀”,用“1”来表示每个“嗒”,并且把他们放在一个字符串关联数组中。定义莫斯代码编码表的PHP代码就像下面这样:
  $CWCODE = array ('A'=>'01','B'=>'1000','C'=>'1010','D'=>'100','E'=>'0','F'=>'0010','G'=>'110','H'=>'0000','I'=>'00','J'=>'0111','K'=>'101','L'=>'0100','M'=>'11','N'=>'10', 'O'=>'111','P'=>'0110','Q'=>'1101','R'=>'010','S'=>'000','T'=>'1','U'=>'001','V'=>'0001','W'=>'011','X'=>'1001','Y'=>'1011','Z'=>'1100', '0'=>'11111','1'=>'01111','2'=>'00111','3'=>'00011','4'=>'00001','5'=>'00000','6'=>'10000','7'=>'11000','8'=>'11100','9'=>'11110','.'=>'010101',','=>'110011','/'=>'10010','-'=>'10001','~'=>'01010','?'=>'001100','@'=>'00101');
  需要注意的是,如果你特别在意内存占用的话,上面的代码可以解释为位(bit)。给每个代码增加一个开始位,就可以形成一个位的模式,每个字符就可以用一个字节来储存。同时,当解析最终编码的时候,要删除开始位左边的位(bit),从而获得真正的变长编码。
 
  PHP内核探索之PHP中的哈希表
  PHP中的HashTable是采用了向量加双向链表的实现方式,向量在arBuckets变量保存,向量包含多个bucket的指针,每个指针指向由多个bucket组成的双向链表,新元素的加入使用前插法,即新元素总是在bucket的第一个位置。由上面可以看到,PHP的哈希表实现相当复杂。这是它使用超灵活的数组类型要付出的代价。
  在PHP内核中,其中一个很重要的数据结构就是HashTable。我们常用的数组,在内核中就是用HashTable来实现。那么,PHP的HashTable是怎么实现的呢?最近在看HashTable的数据结构,但是算法书籍里面没有具体的实现算法,刚好最近也在阅读PHP的源码,于是参考PHP的HashTable的实现,自己实现了一个简易版的HashTable,总结了一些心得,下面给大家分享一下。
  笔者github上有一个简易版的HashTable的实现:HashTable实现另外,我在github有对PHP源码更详细的注解。感兴趣的可以围观一下,给个star。PHP5.4源码注解。可以通过commit记录查看已添加的注解。
  HashTable的介绍
  哈希表是实现字典操作的一种有效数据结构。
  定义
  简单地说,HashTable(哈希表)就是一种键值对的数据结构。支持插入,查找,删除等操作。在一些合理的假设下,在哈希表中的所有操作的时间复杂度是O(1)(对相关证明感兴趣的可以自行查阅)。
  实现哈希表的关键
  在哈希表中,不是使用关键字做下标,而是通过哈希函数计算出key的哈希值作为下标,然后查找/删除时再计算出key的哈希值,从而快速定位元素保存的位置。
  在一个哈希表中,不同的关键字可能会计算得到相同的哈希值,这叫做“哈希冲突”,就是处理两个或多个键的哈希值相同的情况。解决哈希冲突的方法有很多,开放寻址法,拉链法等等。
  因此,实现一个好的哈希表的关键就是一个好的哈希函数和处理哈希冲突的方法。
  Hash函数
  判断一个哈希算法的好坏有以下四个定义: > * 一致性,等价的键必然产生相等的哈希值; > * 高效性,计算简便; > * 均匀性,均匀地对所有的键进行哈希。
  哈希函数建立了关键值与哈希值的对应关系,即:h = hash_func(key)。对应关系见下图:
  hash-exam
  设计一个完美的哈希函数就交由专家去做吧,我们只管用已有的较成熟的哈希函数就好了。PHP内核使用的哈希函数是time33函数,又叫DJBX33A,其实现如下:
  static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength){
  register ulong hash = 5381;
  /* variant with the hash unrolled eight times */for (; nKeyLength >= 8; nKeyLength -= 8) {hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  hash = ((hash << 5) + hash) + *arKey++;
  }
  switch (nKeyLength) {
  case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 1: hash = ((hash << 5) + hash) + *arKey++; break;case 0: break;
  EMPTY_SWITCH_DEFAULT_CASE()
  }
  return hash;
  }
  注:函数使用了一个8次循环+switch来实现,是对for循环的优化,减少循环的运行次数,然后在switch里面执行剩下的没有遍历到的元素。
 
  PHP程序员的简单运维
  所谓的简单运维就是保证自己开发的程序能正常运行和使用。当一个程序员需要兼作运维时候需要掌握本文讲述的技能。
  所谓的简单运维就是保证自己开发的程序能正常运行和使用。
  当一个程序员需要兼作运维时候需要掌握以下技能1、linux系统基础命令和Windows Server操作
  是基础中的基础,ls, rm, top, w, mkdir, find, cp, mv, kill, killall, cat, chown, chmod, time... 等等,命令参数没必须全部掌握,需要用的时候度娘去查。
  2、WEB服务环境配置
  常用的NGINX和APACHE要熟悉,WIN下可以使用IIS,有些情况下需要TOMCAT也要了解,一般使用安装包或者安装命令比较省事。后面会介绍一些安装命令。
  3、SHELL脚本或BAT批处理
  简单写个备份脚本或者文件处理之类的,方便快捷。
  4、数据库
  大部分使用MYSQL,一般掌握数据迁移,坏损数据修复即可。
  5、防火墙(安全规则)
  WIN一般使用IP策略,linux用IPTABLES和hosts.allow即可防范常规的非授权访问,后面也有详细介绍。
  6、监控工具(存货监控)
  相对来说比较重要,保证业务正常运行的手段,有条件的话可以自己写监控报警脚本,也可以使用第三方工具 cacti,nagios,zabbix等等。也有部分公司提供监控服务,如监控宝,阿里云监控,百度云观测,360监控,业务出错后都有短信或者邮件等渠道通知。
  7、集群和热备
  有很多工具可以实现,根据实际情况部署即可,对于WEB服务基本就两点:文件和数据库。
  8、数据备份
  通过脚本或者工具把所有业务数据定期异地备份,一般情况是凌晨1点-3点在服务器空闲时间。
 

上一篇:PHP继承竟然也需要显性基因?

下一篇:PHP中的字符串函数说明