“程序设计”目录存档

用VBS下载文件

2010年06月17日,星期四

Google一下关键词“VBS 下载文件”出来也是一堆一样的,你复制我的,我复制你的,复制来复制去最后不知道是谁的。不过基本都是对的了,原理都一样,使用msxml2.xmlhttp和adodb.stream对象。至于他们所说的第二种方法,使用internet.application对象下载文件,我没有测试过,不知道效果怎么样。

Sub download(url,target)
	Const adTypeBinary = 1
	Const adSaveCreateOverWrite = 2
	Dim http,ado
	Set http = CreateObject("Msxml2.XMLHTTP")
	http.open "GET",url,False
	http.send
	Set ado = createobject("Adodb.Stream")
	ado.Type = adTypeBinary
	ado.Open
	ado.Write http.responseBody
	ado.SaveToFile target
	ado.Close
End Sub

download "https://demon.tw/foo.gif","foo.gif"

代码很简单,我就不多说什么了。我好奇的是他们说这段代码杀毒软件会报毒,我没有测试过不知道会不会报毒,但是这句话表明了他们的不良企图。呵呵,原来大家都喜欢编病毒啊。

Asc/AscB/AscW和Chr/ChrB/ChrW函数之间的区别

2010年06月15日,星期二

翻译自微软帮助和支持,感谢公子的大力协助。http://support.microsoft.com/kb/145745/en-us/

概要:多年来,BASIC程序员一直使用Asc和Chr函数来访问和操作ASCII字符集。随着Unicode被主流操作系统和应用程序所接受,需要改进版本的Asc和Chr函数已经开发了。为了满足这种需求,针对Windows系统的Microsoft Visual Basic(4.0以及更高版本)包括了AscB、ChrB和AscW、ChrW函数。

更多信息:Unicode是一种为代替ANSI标准而设计的,把字符编码成数值形式的标准。因为ANSI标准只使用单个字节来代表每个字符,它受最大256个字符的限制。虽然这对于英语受众来说已经足够,但当考虑到全球软件市场时,它无法满足。使用Unicode标准,每个字符由两个字节表示,因此整个的Unicode字符集包括了65536个可能的位置。

微软的Windows NT, Windows 2000, and Microsoft OLE 2.0完全基于Unicode设计,而且Visual Basic(4.0以及更高版本)在内部使用Unicode格式来表示所有的字符串。AscW和ChrW函数允许对Unicode字符的全范围访问。这些函数和原始的Asc、Chr函数运行方式相同,唯一的区别在于新函数支持0到65536的参数,而原来的只能是0到255。许多Visual Basic对象(例如调试窗口、标签、文本框),当它们不知道怎样显示一个Unicode字符时,会返回一个“?”。

因为所有的字符串现在在内部由Unicode格式表示,它不像以前表示一个字符串里的二进制数据那样简单。使用Chr函数来分配数据给一个字符串的结果不再向以前一样。例如:

stringvar = Chr(65)

结果是一个两字节长的字符串,其中第一字节的值为65,第二字节的值为0(这是Unicode表示的字母“A”)。需要记住的是,从ANSI转换至Unicode并不总是意味着像这个例子里做的那样,仅仅添加一个值为0的第二字节。例如,大多数在130~159范围内的ANSI字符码拥有完全不同的Unicode值。尝试运行’Debug.Print AscW(Chr(130))’,然后一个8218的值会显示出来。

(更多…)

用VBS实现PHP的urlencode函数

2010年06月13日,星期日

昨天是JavaScript的,今天换成VBScript版的urlencode函数了,好吧,我承认我很无聊。我写代码之前Google过关键词“VBS urlencode函数”,结果出来的前三个链接(你搜索的结果可能和我不一样)是:。(原谅我不喜欢直接贴链接)好家伙,代码一模一样,一模一样不要紧,还都是错的。贴出来围观一下(注意这是错的)。

Function URLEncode(strURL)
    Dim I
    Dim tempStr
    For I = 1 To Len(strURL)
        If Asc(Mid(strURL, I, 1)) < 0 Then
            tempStr = "%" & Right(CStr(Hex(Asc(Mid(strURL, I, 1)))), 2)
            tempStr = "%" & Left(CStr(Hex(Asc(Mid(strURL, I, 1)))), Len(CStr(Hex(Asc(Mid(strURL, I, 1))))) - 2) & tempStr
            URLEncode = URLEncode & tempStr
        ElseIf (Asc(Mid(strURL, I, 1)) >= 65 And Asc(Mid(strURL, I, 1)) <= 90) Or (Asc(Mid(strURL, I, 1)) >= 97 And Asc(Mid(strURL, I, 1)) <= 122) Or (Asc(Mid(strURL, I, 1)) >= 48 And Asc(Mid(strURL, I, 1)) <= 57) Then
            URLEncode = URLEncode & Mid(strURL, I, 1)
        Else
            URLEncode = URLEncode & "%" & Hex(Asc(Mid(strURL, I, 1)))
        End If
    Next
End Function

连“-_.”这几个符号都一起encode,忽悠广大的人民群众么。退一步讲,假设代码是正确的吧,这代码的效率不敢恭维。我觉得我写代码已经够不讲究效率了,原来还有比我更强的人。每循环一次都要计算一次Len(strURL),然后是出现无数次的Asc(Mid(strURL, I, 1)) 。现在的人到底在想什么,难道看都不看就Ctrl+C,Ctrl+V吗?

由于不同编码的中文字符urlencode的结果是不一样的,我写了两个版本的urlencode函数,一个是ANSI版的,一个是UTF-8版的。这里的ANSI和UTF-8指的不是VBS文件保存的编码,而是指对应的PHP编码,即ANSI版的对应以gb2312编码的PHP字符串的urlencode,UTF-8版的对应以UTF-8编码的PHP字符串的urlencode。以“恶魔”为例,使用ANSI版的urlencode后输出%B6%F1%C4%A7,而UTF-8版的输出%E6%81%B6%E9%AD%94。

代码懒得贴出来了,直接下载吧,有什么问题请留言指正,目前我测试的样本都没有问题,也许是样本不够多吧。

ANSI版的urlencode

[download id=11]

UTF-8版的urlencode

[download id=12]

用JavaScript实现PHP的urlencode函数

2010年06月11日,星期五

在写JavaScript(严格的说是JScript)版的六维空间作弊工具时(怎么又是这句话。。。其实我早就写完了。。。)需要用到PHP的urlencode函数,于是Google之,发现有几种说法。

有的说用JavaScript自带的encodeURIComponent函数即可实现,真是睁着眼睛说瞎话。不解释,自己测试一下就知道JavaScript的encodeURIComponent的PHP的urlencode是不一样的。有的给出了由VBScript和JavaScript混合编写的urlencode,对不对我没有测试,即使对,也只有IE兼容VBScript。还有的贴出一段不知道是自己写的还是哪里转来的代码,都不测试一下对不对就公布出来。

根据我的经验,中文一般是搜不出什么好代码的,用英文的Google搜索,找到三个不同的版本实现,phpjs.orgwebtoolkit.infocass-hacks.com。第一个给出的函数可以直接使用,第二个给出的Url变量也可以直接使用,第三个给出的函数也是对的,但是要保证输入的参数是UTF-8编码。传说JavaScript的内部采用的是UTF-16编码(是不是我也不知道,传说而已),所以要使用第三个函数需要先把字符串转成UTF-8。幸好这个牛人提供了这样一个函数,把两个结合起来就完成了JavaScript版的urlencode函数。代码太长久不贴出来了,直接下载把,下面是在线演示(注意在博客首页无法演示)


注:不同编码下中文的urlencode是不同的,例如“恶魔”在UTF-8编码下urlencode后为%E6%81%B6%E9%AD%94,而在gb2312编码下urlencode后为%B6%F1%C4%A7。鉴于UTF-8比较普遍,本代码仅实现了UTF-8编码的PHP urlencode函数

下载程序代码[download id=9]

用C语言实现PHP的urlencode函数

2010年06月9日,星期三

题目好像弄错了,PHP本身就是用C语言写,所以准确来说题目应该是PHP的urlencode函数的C语言源码。在用C语言写某个程序(至于是什么程序,参见其他文章)的时候要用到PHP的urlencode函数。好在PHP是开源的,就搜索了一下PHP的源码,在php-5.3.2\ext\standard\url.c文件中找到了PHP的urlencode函数的C语言源代码,感兴趣的可以下载PHP源码看看。但是因为用到了PHP源码中的其他函数,urlencode的源代码不能直接用到C语言程序中,我参考源码修改了一下,就可以直接使用了。代码如下,s为需要urlencode的字符串,len为字符串的长度,new_length为urlencode后新字符串的长度:

char *php_url_encode(char const *s, int len, int *new_length)
{
	#define safe_emalloc(nmemb, size, offset)	malloc((nmemb) * (size) + (offset))
	static unsigned char hexchars[] = "0123456789ABCDEF";
	register unsigned char c;
	unsigned char *to, *start;
	unsigned char const *from, *end;
	
	from = (unsigned char *)s;
	end = (unsigned char *)s + len;
	start = to = (unsigned char *) safe_emalloc(3, len, 1);

	while (from < end) {
		c = *from++;

		if (c == ' ') {
			*to++ = '+';
#ifndef CHARSET_EBCDIC
		} else if ((c < '0' && c != '-' && c != '.') ||
				   (c < 'A' && c > '9') ||
				   (c > 'Z' && c < 'a' && c != '_') ||
				   (c > 'z')) {
			to[0] = '%';
			to[1] = hexchars[c >> 4];
			to[2] = hexchars[c & 15];
			to += 3;
#else /*CHARSET_EBCDIC*/
		} else if (!isalnum(c) && strchr("_-.", c) == NULL) {
			/* Allow only alphanumeric chars and '_', '-', '.'; escape the rest */
			to[0] = '%';
			to[1] = hexchars[os_toascii[c] >> 4];
			to[2] = hexchars[os_toascii[c] & 15];
			to += 3;
#endif /*CHARSET_EBCDIC*/
		} else {
			*to++ = c;
		}
	}
	*to = 0;
	if (new_length) {
		*new_length = to - start;
	}
	return (char *) start;
}

不想复制粘贴的可以直接下载源码

[download id=10]