Delphi实现数学表达式的计算(逆波兰式法)-四则运算解析

原帖地址:https://www.cnblogs.com/tangqs/archive/2011/11/03/2234715.html

本文主要内容为123发表于 2011-5-31 00:19:55发表的“逆波兰表达式,北大未名湖站 – 编程技术 – 必度!”帖子

http://www2.pekdo.com/forum.php?mod=viewthread&tid=32&page=1

但帖子中的内容很多不够完善,比如左右单目符号、函数名、函数参数、逗号等都没有给出处理方式,

我做较大的改进,用Delphi 7做了测试,并公开源代码供大家参考,相互学习!

程序下载地址ExpCalculator.rar

源代码下载地址ExpCalcV2.3.rar 

   众所周知,计算机处理表达式的难点在于括号的处理,在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,所以,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法。按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。如a+b表达为ab+。这种后缀表达式非常方便去掉运算符优先级的影响与括号,甚至是单目运算符:

示例说明:

1. a*b+c*(d+e)   逆波兰表达式: ab*cde+*+

2. -a+-b*+c        逆波兰表达式: a~b~c@*+

3.a-(-(b-c))       逆波兰表达式: abc-~ –

预处理:

-(负号)处理:用~代替

+(正号)处理:用@代替,或者将其在字符串中删除

数学自然常数 e 与圆周率 pi 的用  (2.718281828459045)  与 (3.1415926535897932384) 代替(包含前后的括弧)

那么计算机怎样通过后缀式来进行运算呢?这里首先假设读取分析表达式的准备工作都已经做好了,那么首先需要做的是把表达式转换成后缀式,也就是逆波兰表达式的构建过程。

构建器由两个主要组件组成,一个是目标表达式的存储器,另一个是一个符号栈。与源表达式的扫描顺序一样,存储器是从左向右储存数据的,而符号栈则遵守后进先出的原则:

* 读入一个数据(数值与函数名非单个字符,需要做判断处理)

1. 如果是左单目运算符或者函数名,直接入符号栈;比如 正负号 ~ @ max sin

2. 如果是右单目运算符,直接入存储器栈;比如 阶乘!与百分号%

3. 如果是运输量,则直接写入存储器;检查符号栈顶是否有单目运算符,有的话则全部出栈,并写入存储器;

4. 如果是左括号”(“,则直接入符号栈;

5. 如果是右括号”)”,则弹出符号栈数据,写入存储器,一直到左括号弹出,再检查栈顶是否为左单目运算符或者函数名,是的话继续弹出,直到遇到双目运算符;

6. 如果是普通运算符,则与栈顶符号比较优先级,若大于栈顶优先级,则入栈;否则弹出栈顶符号并写入存储器,直到栈顶符号的运算优先级较小为止;

7.如果是函数参数的连接逗号“,”时,则弹出符号栈数据,直到遇到左括弧(或者逗号为止,再将逗号,入符号栈;

8.如果是结束符(表示表达式已全部读完),则符号栈全部弹出并写入存储器,否则读取数据进入下个过程;

此外还有一些处理的技巧,比如定义一个优先级最低的运算符作为表达式结束的标志(用#标示,添加在表达式结尾处),在符号栈里首先加入一个结束标志,那么表达式读完时则自动弹出栈中所有符号,并写入存储器结尾表示成功。

接下来是计算的过程。计算的时候除了刚才构建的数据外,还需要另外一个计算中间值存储栈。

1、首先是从左至右扫描数据段,如果读出的是数据则压入计算中间值存储栈

2、遇到单目运算符号就从计算中间值存储栈弹出一个数据进行运算,再把结果压回计算中间值存储栈

3、遇到双目运算符号就从计算中间值存储栈弹出两个数据进行运算,再把结果压回计算中间值存储栈;这里需要注意减法与除法的计算顺序是第一次弹出的值作为减数和除数,第二次弹出的值作为被减数和被除数。

4、遇到逗号,就从计算中间值存储栈弹出两个数据用“,”连接起来直接将数值字符串压入计算中间值存储栈,不做计算。比如12 13压入13,12

5、遇到函数,弹出计算中间值存储栈的相关数据调用函数进行计算;

这样,返回结果就是栈中唯一的数据,我们完成了逆波兰表达式的全部计算过程。

以下为以上算法的详细演示示例:

基于逆波兰式法的数学表达式计算算法举例演示

http://www.cnblogs.com/tangqs/archive/2012/05/18/2507708.html

 最后还有一点就是检查给定表达式是否正确,就是下面的 

function CheckCalcExp(const ExpT: string; var AInfo: string): boolean;

这样保证计算不会出错,具体见代码。

  /* 表达式计算 */

  /* 调用方式:CalcExp(‘1+max(0.5,sin(1))+sum(1,2^3,mod(5,3))’, res, infoStr)   */

  /* 带符号参数调用方法,先调用符号定义AddSignParam,再调用 CalcExp:*/

  /* AddSignParam([‘a’,’s’], [1, 0.5]);  或者 AddSignParam(‘a=1,s=0.5’)  */

  /* CalcExp(‘1+a+sin(s)’, res, infoStr)  */

  /* 其中res存储计算结果,为double型;infoStr存储计算时的提示信息,为string */

表达式计算器 V2.3 支持以下功能:

 1、四则运算 + – * / 、括弧()、正负(+ -)

 2、百分数 %、求幂 ^ 、整数阶乘 ! (1 至 150)

 3、参数符号计算,示例:a+b @@a=1,b=2 结算结果为3

                  用@@表示表达式中定义符号的值

 4、常数e、圆周率PI

 5、丰富的函数功能:

    统计函数:    max,min,sum,avg,stddev 标准偏差,均支持多参数

    三角函数:     sin,cos,tan,arcsin,arccos,arctan

                     degrad(60)   角度转弧度

                     raddeg(3.14) 弧度转角度

                     costh(a,b,c) 余弦定理 cosC)

    指数对数函数:sqrt,power(x,y),abs,exp,log2,log10,logN(a,N),ln

    数据处理函数:int(x),trunc(x) 取整

                        frac(x) 取小数部分

                        round(x) 四舍五入取整

                        roundto(x,-1) 保留一位小数

                        mod(M,N) 求模

    几何面积函数:s_tria(a,b,c) 三角形面积

                        s_circ(r)     圆形面积

                        s_elli(a,b)   椭圆面积

                        s_rect(a,b)   矩形面积

                        s_poly(a,n)   正多边形面积

    平面几何函数:pdisplanes(x1,y1,x2,y2) 平面两点距离

                        pdisspace(x1,y1,z1,x2,y2,z2) 空间两点

                        p_line(x0,y0, A, B, C) 平面点到线距离

                        p_planes(x0,y0,z0 A, B, C, D)空间点到面距离

       数列求和:    sn(a1, d, n) 等差数列前n项和

                        sqn(a1, q, n) 等比数列前n项和

       个税计算函数:intax(x), arcintax(x) 个税反算

    6 、历史计算记录,双击计算记录可重新修改计算

   示例: sin(1)+(-2+(3-4))*20% , e^63+PI , 15! , log2(max(2,3))

   注: 运算符必须为半角格式,三角函为弧度,输入可用空格间隔

brew 更新

为什么要定期更新
我发现不少人都不会经常更新,或者只在必须用某个工具的新版本的时候才更新。他们的看法是,更新有可能产生一些意外的问题,反正当前环境足够稳定可以用,干嘛自找麻烦呢?

这个看法对也不对。对是因为,更新产生的潜在问题不可避免。不对是因为总有一天你需要升级的,也许是为了某个工具的新特性,也许是为了修复软件的漏洞,也许你安装的包非要依赖另一个包的新版本,等等。如果隔了很长一段时间才升级,那潜在的小问题可能就会变成大问题。

另一个有意思的现象是,当碰到比较破坏性的事情,比如 Mac OS 大版本更新后,很多人会选择重装 Homebrew 然后顺带安装最新版的包。很少人会去装一个指定的旧版本(除了特殊项目需要)。这说明他们不是不想用新版本,而是不想痛苦地更新。

既然总有一天需要更新,而更新带来问题不可避免,那为什么不更新得频繁点呢?这个道理跟 Git 的冲突解决有相似性。长时间不 pull/push 的代码更容易产生冲突,一个解决方法就是频繁地 commit & merge 。

我现在试着一个月更新一次,两次下来发现这些好处:
每次更新的包很少,更新风险也小。
更容易发现不需要的包,便于清理,不为不需要的东西买单。
定期清理旧版本,释放空间。
更新流程其实都差不多,下面列一下我常用的命令。

更新 Homebrew
要获取最新的包的列表,首先得更新 Homebrew 自己。这可以用 brew update 办到。

brew update

完后会显示可以更新的包列表,其中打钩的是已经安装的包。输出类似下面这样:

Updated Homebrew from fe93aa3 to 6ae64c3.
Updated 1 tap (homebrew/versions).
==> Updated Formulae
awscli cmake ✔ homebrew/versions/libmongoclient-legacy

更新包 (formula)
更新之前,我会用 brew outdated 查看哪些包可以更新。

brew outdated

然后就可以用 brew upgrade 去更新了。Homebrew 会安装新版本的包,但旧版本仍然会保留。

brew upgrade # 更新所有的包
brew upgrade $FORMULA # 更新指定的包

清理旧版本
一般情况下,新版本安装了,旧版本就不需要了。我会用 brew cleanup 清理旧版本和缓存文件。Homebrew 只会清除比当前安装的包更老的版本,所以不用担心有些包没更新但被删了。

brew cleanup # 清理所有包的旧版本
brew cleanup $FORMULA # 清理指定包的旧版本
brew cleanup -n # 查看可清理的旧版本包,不执行实际操作

这样一套下来,该更新的都更新了,旧版本也被清理了。

锁定不想更新的包
如果经常更新的话,brew update 一次更新所有的包是非常方便的。但我们有时候会担心自动升级把一些不希望更新的包更新了。数据库就属于这一类,尤其是 PostgreSQL 跨 minor 版本升级都要迁移数据库的。我们更希望找个时间单独处理它。这时可用 brew pin 去锁定这个包,然后 brew update 就会略过它了。

brew pin FORMULA   # 锁定某个包  
brew unpin FORMULA # 取消锁定

其他几个常用命令
brew info 可以查看包的相关信息,最有用的应该是包依赖和相应的命令。比如 Nginx 会提醒你怎么加 launchctl ,PostgreSQL 会告诉你如何迁移数据库。这些信息会在包安装完成后自动显示,如果忘了的话可以用这个命令很方便地查看。

brew info $FORMULA # 显示某个包的信息
brew info # 显示安装了包数量,文件数量,和总占用空间
brew deps 可以显示包的依赖关系,我常用它来查看已安装的包的依赖,然后判断哪些包是可以安全删除的。

brew deps –installed –tree # 查看已安装的包的依赖,树形显示

输出如下:

elixir (required dependencies)
└── :erlang

wxmac (required dependencies)
├── jpeg
├── libpng
│ └── xz
└── libtiff
└── jpeg

还有很多有用的命令和参数,没事 man brew 一下可以涨不少知识。

小结
不想更新 Homebrew 往往有两个原因,害怕潜在的风险和对工具的不熟悉,我之前也是这样。写这篇文章最开始是为了帮我记录常用的命令方便以后查阅的。希望它也能帮到你。

《滕王阁序》

  豫章故郡,洪都新府。星分翼轸,地接衡庐。襟三江而带五湖,控蛮荆而引瓯越。物华天宝,龙光射牛斗之墟;人杰地灵,徐孺下陈蕃之榻。雄州雾列,俊采星驰。台隍枕夷夏之交,宾主尽东南之美。都督阎公之雅望,棨戟遥临;宇文新州之懿范,襜帷暂驻。十旬休假,胜友如云;千里逢迎,高朋满座。腾蛟起凤,孟学士之词宗;紫电青霜,王将军之武库。家君作宰,路出名区;童子何知,躬逢胜饯。

  时维九月,序属三秋。潦水尽而寒潭清,烟光凝而暮山紫。俨骖騑于上路,访风景于崇阿;临帝子之长洲,得天人之旧馆。层峦耸翠,上出重霄;飞阁流丹,下临无地。鹤汀凫渚,穷岛屿之萦回;桂殿兰宫,即冈峦之体势。

  披绣闼,俯雕甍,山原旷其盈视,川泽纡其骇瞩。闾阎扑地,钟鸣鼎食之家;舸舰弥津,青雀黄龙之舳。云销雨霁,彩彻区明。落霞与孤鹜齐飞,秋水共长天一色。渔舟唱晚,响穷彭蠡之滨;雁阵惊寒,声断衡阳之浦。

  遥襟甫畅,逸兴遄飞。爽籁发而清风生,纤歌凝而白云遏。睢园绿竹,气凌彭泽之樽;邺水朱华,光照临川之笔。四美具,二难并。穷睇眄于中天,极娱游于暇日。天高地迥,觉宇宙之无穷;兴尽悲来,识盈虚之有数。望长安于日下,目吴会于云间。地势极而南溟深,天柱高而北辰远。关山难越,谁悲失路之人?萍水相逢,尽是他乡之客。怀帝阍而不见,奉宣室以何年?

  嗟乎!时运不齐,命途多舛。冯唐易老,李广难封。屈贾谊于长沙,非无圣主;窜梁鸿于海曲,岂乏明时?所赖君子见机,达人知命。老当益壮,宁移白首之心?穷且益坚,不坠青云之志。酌贪泉而觉爽,处涸辙以犹欢。北海虽赊,扶摇可接;东隅已逝,桑榆非晚。孟尝高洁,空余报国之情;阮籍猖狂,岂效穷途之哭!

  勃,三尺微命,一介书生。无路请缨,等终军之弱冠;有怀投笔,慕宗悫之长风。舍簪笏于百龄,奉晨昏于万里。非谢家之宝树,接孟氏之芳邻。他日趋庭,叨陪鲤对;今兹捧袂,喜托龙门。杨意不逢,抚凌云而自惜;钟期既遇,奏流水以何惭?

  呜乎!胜地不常,盛筵难再;兰亭已矣,梓泽丘墟。临别赠言,幸承恩于伟饯;登高作赋,是所望于群公。敢竭鄙怀,恭疏短引;一言均赋,四韵俱成。请洒潘江,各倾陆海云尔:

  滕王高阁临江渚,佩玉鸣鸾罢歌舞。

  画栋朝飞南浦云,珠帘暮卷西山雨。

  闲云潭影日悠悠,物换星移几度秋。

  阁中帝子今何在?槛外长江空自流。

注释译文

词句注释

  1. 滕王阁:为唐高祖的儿子滕王李元婴任洪州都督时修建,旧址在今江西南昌江之滨。
  2. 豫章故郡,洪都新府:豫章是汉朝设置的,治所在南昌,所以说“故郡”。唐初把豫章郡改为“洪州”,所以说“新府”。“豫章”一作”南昌”。
  3. 星分翼轸(zhěn):(洪州)属于翼、轸二星所对着的地面的区域。古人用天上二十八宿(列星)的方位来区分地面的区域,某个星宿对看地面的某个区域,叫做某地在某星的分野。衡庐:指湖南的衡山和江西的庐山。
  4. 襟三江而带五湖:以三江为襟,以五湖为带。三江,泛指长江中下游。旧说古时长江流过彭蠡(今鄱阳湖),分成三道入海,故称“三江”。五湖,泛指太湖区域的湖泊。一说指太湖、鄱阳湖、青草湖、丹阳湖、洞庭湖,南昌在五湖之间。
  5. 控蛮荆而引瓯(ōu)越:控制楚地,连接瓯越。蛮荆,古楚地(今湖北、湖南一带),这是沿用古代的说法。瓯越,就是东瓯,今浙江永嘉一带。
  6. 物华天宝,龙光射牛斗之墟:物的精华就是天的珍宝,宝剑的光芒直射(天上)牛、斗二星所在的区域。
  7. 人杰地灵,徐孺下陈蕃之榻:人有俊杰是因为地有灵秀(之气),徐孺子在太守陈蕃家中下榻。徐孺,名稚,字孺子,南昌人,东汉时名士,家贫,常亲自耕种,德行为人所景仰。当时陈蕃为豫章太守,素来不接待宾客,专为徐稚设一榻,平时挂起,只有徐稚来访才放下。因此后世有“下榻”的说法。下,名词使动用法,使……放下。榻,狭长而低矮的坐卧用具。
  8. 雄州雾列:雄伟的大州像雾一样涌起,形容洪州的繁盛。
  9. 俊采星驰:杰出的人才像星星一样,形容人才之多。星驰,众星是运行着的,所以说“驰”。
  10. 台隍(huáng)枕夷夏之交:南昌城处在瓯越与中原接壤的地方。这是说洪州处于要害之地。台隍,城台和城池,这里指南昌城。夷,古代称少数民族为夷,这里指上文所说的蛮荆、瓯越之地。夏,古代汉族自称夏,这里指中原地区。交,动词活用名词,接壤的地方。
  11. 宾主尽东南之美:(来赴这次宴会的)客人和主人,都是东南一带的俊杰。主,指洪州都督阎公,名字不详。美,形容词活用名词,俊杰。
  12. 都督阎公之雅望,棨(qǐ)戟(jǐ)遥临;宇文新州之懿(yì)范,襜(chān)帷暂驻:有崇高声望的都督阎公远道来临,有美好德行的新州刺史宇文氏在此地暂时停留。棨戟,有套的戟,古时官吏出行时用做前导的一种仪仗。都督的仪仗到了,也就是说阎公光临。新州,州名,今广东新兴。襜帷,车的帷幔,这里借指宇文新州的车马。
  13. 十旬休假:指恰好赶上十日休假的日子。当时官员十天休息一天,叫做“旬休”。
  14. 千里逢迎:指迎接千里而来的客人。
  15. 腾蛟(jiāo)起凤,孟学士之词宗:文坛上众望所归的孟学士,文章的辞采有如蛟龙腾空,凤凰飞起(那样灿烂夺目)。孟学士,名字不详。学士,掌管文学撰述的官。
  16. 紫电青霜,王将军之武库:王将军的兵器库里藏有锋利的宝剑,意在显示王将军的勇武和韬略。紫电,古宝剑名。《古今注》:“吴大皇帝(孙权)有宝剑六,二曰紫电。”青霜,也指剑。《西京杂记》卷一:“高祖斩白蛇剑,……刃上常若霜雪。”也可写作“清霜”。王将军,名字不详。
  17. 家君作宰,路出名区;童子何知,躬逢胜饯(jiàn):家父作交趾县的县令,自己因探望父亲路过这个有名的地方(指洪州);年幼无知,(却有幸)参加这场盛大的宴会。宰,县令,这里指交趾县的县令。何,宾语前置,应为“知何”,懂得什么。
  18. 时维九月,序属三秋:指当时正是深秋九月。维,句中语气词。三秋,秋季,这里指秋天的第三个月,即九月。
  19. 俨骖(cān)騑(fēi)于上路:驾着车在高高的道路上(前行)。
  20. 临帝子之长洲,得天人之旧馆:意思是说到滕王阁来观赏。长洲,指滕王阁前的沙洲。有版本为“得仙人之旧馆”。
  21. 层峦耸翠,上出重霄;飞阁流丹,下临无地:(在这里可以望见)重叠的峰峦耸起一片苍翠,上达重霄;凌空架起的阁道上,涂饰的朱红色油彩鲜艳欲滴,从阁道往下看,地好像没有了似的。飞阁,架空建筑的阁道。流,形容彩画鲜艳欲滴。丹,丹漆,这里泛指彩绘。临,从高处往下探望。飞阁流丹一作飞阁翔丹。
  22. 鹤汀凫(fú)渚(zhǔ),穷岛屿之萦(yíng)回;桂殿兰宫,即冈峦之体势:鹤、野鸭止息的水边平地和小洲,极尽岛屿曲折回环的景致;用桂木、木兰修筑的宫殿,(高低起伏)像冈峦的样子。桂、兰,两种名贵的树,这里是形容宫殿的华丽、讲究。
  23. 披绣闼(tà),俯雕甍(méng):打开精美的阁门,俯瞰雕饰的屋脊。绣,指雕刻得精美细致。
  24. 山原旷其盈视,川泽纡其骇瞩:放眼远望,辽阔的山岭、平原充满人们的视野,迂回的河流、湖泽让人看了吃惊。盈视,极目遥望,满眼都是。骇瞩,对所见的景物感到惊异。
  25. 闾(lǘ)阎(yán)扑地,钟鸣鼎食之家;舸(gě)舰弥津,青雀黄龙之舳:房屋遍地,有不少官宦人家;船只停满渡口,有许多装饰着青雀、黄龙头形的大船。闾阎,里门,这里代指房屋。钟鸣鼎食之家,指大家世族,因古代贵族吃饭时要鸣钟列鼎,鼎中盛食物。青雀黄龙之舳,船头作鸟头形、龙头形。
  26. 云销雨霁(jì),彩彻区明:云消雨停,阳光普照,天空明朗。
  27. 彭蠡(lǐ):古代大泽,即现在的鄱阳湖。
  28. 声断衡阳之浦:鸣声到衡阳之浦而止。断,止。相传衡阳有回雁峰,雁至此就不再南飞,待春而回。
  29. 遥襟甫畅,逸兴遄(chuán)飞:登高望远的胸怀顿时舒畅,飘逸脱俗的兴致油然而生。
  30. 爽籁(lài)发而清风生,纤歌凝而白云遏(è):宴会上,排箫响起,好像清风拂来;柔美的歌声缭绕不散,遏止了白云飞动。爽,形容籁的发音清脆。籁,排箫,一种由多根竹管编排而成的管乐器。
  31. 睢(suī)园绿竹,气凌彭泽之樽(zūn):今日的宴会,好比当年睢园竹林的聚会,在座的文人雅士,豪爽善饮的气概超过了陶渊明。睢园,西汉梁孝王在睢水旁修建的竹园,他常和一些文人在此饮酒赋诗。
  32. 邺(yè)水朱华,光照临川之笔:这是借诗人曹植、谢灵运来比拟参加宴会的文人。邺,今河北临漳,是曹魏兴起的地方。曹植曾在这里作过《公宴诗》,诗中有“朱华冒绿池”的句子。临川之笔,指谢灵运,他曾任临川(今属江西)内史。
  33. 四美:指良辰、美景、赏心、乐事。
  34. 睇(dì)眄(miǎn):看。
  35. 识盈虚之有数:知道事务的兴衰成败是有定数的。
  36. 望长安于日下,目吴会于云间:远望长安,遥看吴会。长安,唐朝的国都。吴会,吴地的古称。
  37. 地势极而南溟(míng)深,天柱高而北辰远:地势偏远,南海深邃;天柱高耸,北极星远悬。天柱,《神异经》记载,昆仑山上铜柱,高入天穹,叫做“天柱”。北辰,北极星,这里暗指国君。
  38. 帝阍(hūn):原指天帝的守门者。这里指皇帝的宫门。宣室:汉未央宫前殿正室叫宣室。汉文帝曾坐宣室接见贾谊,谈话到半夜。
  39. 时运不齐:命运不好。不齐,有蹉跎、有坎坷。
  40. 舛(chuǎn):不顺。
  41. 冯唐:西汉人,有才能却一直不受重用。汉武帝时选求贤良,有人举荐冯唐,可是他已九十多岁,难再做官了。李广:汉武帝时的名将,多年抗击匈奴,军功大,却终身没有封侯。
  42. 屈贾谊于长沙,非无圣主:汉文帝本想任贾谊为公卿,但因朝中权贵反对,就疏远了贾谊,任他为长沙王太傅。屈,使动用法,使……屈。
  43. 窜梁鸿于海曲,岂乏明时:使梁鸿逃到海边(隐居),难道不是在政治昌明的时代吗?窜,使动用法,使……逃。梁鸿,东汉人,因作诗讽刺君王,得罪了汉章帝,被迫逃到齐鲁一带躲避。海曲,海隅,指齐鲁一带临海的地方。明时,政治昌明的时代。
  44. 见机:事前洞察事物的动向。达人知命:通达事理的人,知道命运。
  45. 宁移白首之心:哪能在白发苍苍的老年改变心志?
  46. 青云之志:比喻远大崇高的志向。
  47. 酌(zhuó)贪泉而觉爽:喝下贪泉的水,仍觉得心境清爽。古代传说广州有水名贪泉,人喝了这里的水就会变得贪婪。这句是说有德行的人在污浊的环境中也能保持纯正,不被污染。处涸辙以犹欢:处在奄奄待毙的时候,仍然乐观开朗。处涸辙:原指鲋鱼处在干涸的车辙里。比喻人陷入危急之中。《庄子·外物》有鲋鱼在干涸的车辙中求活的寓言。
  48. 北海虽赊(shē),扶摇可接:北海虽然遥远,乘着旋风还可以到达。北海,即《庄子·逍遥游》中的“北冥”。
  49. 东隅已逝,桑榆非晚:早年的时光虽然已经逝去,珍惜将来的岁月,为时还不晚。东隅,指日出的地方,表示早。桑榆,指日落的地方,表示晚。古人有“失之东隅,收之桑榆”的说法。
  50. 孟尝高洁,空余报国之情:孟尝品行高洁,却空有一腔报国热情。这是作者借孟尝以自比,带有怨意。孟尝,东汉人,为官清正贤能,但不被重用,后来归田。
  51. 阮籍猖狂,岂效穷途之哭:怎能效法阮籍不拘礼法,在无路可走时便恸哭而还呢?意思是说,虽然怀才不遇,但也不放任自流。阮籍,三国魏诗人。他有时独自驾车出行,到无路处便恸哭而返,借此宣泄不满于现实的苦闷心情。猖狂,狂放、不拘礼法。
  52. 三尺微命:指地位低下。三尺,士佩三尺长的绅(古代礼服上束带的下垂部分)。微命,犹如说身份卑微。王勃做过虢州参军,所以这样说。
  53. 无路请缨(yīng),等终军之弱冠:自己和终军的年龄相同,却没有请缨报国的机会。请缨,请求皇帝赐给长缨(长绳)。《汉书·终军传》记载,汉武帝想让南越(今广东、广西一带)王归顺,派终军前往劝说,终军请求给他长缨,必缚住南越王,带回到皇宫门前(意思是一定完成使命)。后来用“请缨”指投军报国。弱冠,指二十岁,古代以二十岁为弱年,行冠礼,为成年人。
  54. 投笔:指投笔从军,用班超投笔从戎的典故。宗悫:南朝宋人,少年时很有抱负,说“愿乘长风破万里浪”。
  55. 舍簪(zān)笏(hù)于百龄,奉晨昏于万里:自己宁愿舍弃一生的功名富贵,到万里以外去朝夕侍奉父亲。簪笏,这里代指官职。簪,束发戴冠用来固定帽子的簪。笏,朝见皇帝时用来记事的手版。
  56. 非谢家之宝树,接孟氏之芳邻:自己并不是像谢玄那样出色的人才,却能在今日的宴会上结识各位名士。谢家之宝树,指谢玄。《晋书·谢玄传》记载,晋朝谢安曾问子侄们:“为什么人们总希望自己的子弟好?”侄子谢玄回答:“譬如芝兰玉树,欲使其生于庭阶耳。”后来就称谢玄为谢家宝树。孟氏之芳邻,这里借孟子的母亲为寻找邻居而三次搬家的故事,来指赴宴的嘉宾。
  57. 他日趋庭,叨陪鲤对:过些时候自己将到父亲那里陪侍和聆听教诲。趋庭,快步走过庭院,这是表示对长辈的恭敬。叨,惭愧地承受,表示自谦。鲤对,孔鲤是孔子的儿子,鲤对指接受父亲教诲。事见《论语·季氏》:(孔子)尝独立,(孔)鲤趋而过庭。(子)曰:“学诗乎?”对曰:“未也。”“不学诗,无以言。”鲤退而学诗。他日,又独立,鲤趋而过庭。(子)曰:“学礼乎?”对曰:‘未也。”“不学礼,无以立。”鲤退而学礼。
  58. 捧袂(mèi):举起双袖作揖,指谒见阎公。喜托龙门:(受到阎公的接待)十分高兴,好像登上龙门一样。托,指寄托身子,这是客气话。龙门,地名,在今山西河津西北的黄河中,那里两岸夹山,水险流急,相传鲤鱼跃过龙门则变为飞龙。这里借“登龙门”的说法,表示由于谒见名人而提高了自己的身份。
  59. 杨意不逢,抚凌云而自惜:没有遇到杨得意那样引荐的人,虽有文才也(只能)独自叹惋。这里是以司马相如自比,又叹惜遇不到引荐的人。杨意:即蜀人杨得意,任掌管天子猎犬的官,西汉辞赋家司马相如是由他推荐给汉武帝的。凌云,这里指司马相如的赋。《史记·司马相如传》记载,相如献《大人赋》,“天子大悦,飘飘有凌云之气,似游天地之间”。
  60. 钟期既遇,奏流水以何惭:既然遇到钟子期那样的知音,演奏高山流水的乐曲又有什么羞惭呢?意思是说,遇到阎公这样的知音,自己愿意在宴会上赋诗作文。钟期,即钟子期。《列子·汤问》记载,俞伯牙弹琴,钟子期能听出他是“志在高山”还是“志在流水”,遂成知音。
  61. 难再:难以第二次遇到。
  62. 兰亭已矣:当年兰亭宴饮集会的盛况已成为陈迹了。
  63. 梓(zǐ)泽丘墟:繁华的金谷园也已变为荒丘废墟。梓泽,金谷园的别称,为西晋石崇所建,故址在今河南洛阳西北。
  64. 登高作赋,是所望于群公:登高而作赋,那是在座诸公的事了。《韩诗外传》卷七:“孔子曰:‘君子登高必赋。’”
  65. 恭疏短引:恭敬地写此小序。
  66. 一言均赋,四韵俱成:我这首诗铺陈出来,成为四韵。
  67. 请洒潘江,各倾陆海云尔:请各位宾客竭尽文才,写出好作品。洒、倾各与江、海对应,意思是竭尽才能,写诗作文。潘岳、陆机都是晋朝人,南朝梁人钟嵘的《诗品》云“陆才如海,潘才如江”。云尔,语气助词,用在句尾,表示述说完了。
  68. 騑:也可写作 ?。

白话译文

  这里是汉代的南昌郡城,如今是洪州都督府,天上的方位属于翼、轸两星宿的分野,地上连结着衡山和庐山。以三江为衣襟,以五湖为衣带,控制楚地,连接闽越。这里有物类精华、天产珍宝,宝剑的光芒直冲上牛、斗二星之间。人中有英杰,大地有灵气,陈蕃专为徐孺设下几榻。雄伟的洪州城,房屋像雾般罗列,英俊的人才,像繁星一样活跃。城池座落在夷夏交界之地,主人与宾客,汇集了东南地区的青年才俊。都督阎公,享有崇高的名望,远道来到洪州坐镇;宇文州牧,是美德的楷模,赴任途中在此暂留。正逢十旬休假的日子,杰出的朋友云集,高贵的宾客,也都不远千里来此聚会,文坛领袖孟学士,其文采像腾起的蛟龙、飞舞的彩凤,王将军的武库里,藏有像紫电、青霜一样锋利的宝剑。父亲在交趾做县令,我在探亲途中路过这方宝地;我年幼无知,竟然有幸亲自参加了这次盛大的宴会。

  时值九月深秋,积水消尽,潭水清澈,云烟凝结在暮霭中,山峦呈现一片紫色。在高高的山路上驾着马车,在崇山峻岭中访求风景,来到昔日帝子的长洲,找到仙人居住过的宫殿,这里山峦重叠,山峰耸入云霄。凌空的楼阁,红色的阁道犹如飞翔在天空,从阁上看深不见底、白鹤、野鸭栖息的小洲,极尽岛屿的迂折回环之势,威严的宫殿,依照起伏的山峦而建。

  打开雕花的阁门,俯视华美的屋脊。山峰平原尽收眼底,湖川曲折令人惊叹。房屋密集,不少富贵人家,船只塞满了渡口,都是雕刻着青雀黄龙花纹的大船。雨过天晴,虹消云散,阳光朗照。落霞与孤雁一起飞翔,秋水长天连成一片。傍晚渔舟中传来歌声,响彻彭蠡湖滨,雁群因寒意而长鸣,到衡阳岸边方止。

  放眼远望,心胸顿时舒畅,兴致兴起,排箫的音响引来了清风,柔缓的歌声令白云陶醉,像在睢园竹林的聚会,宴会上的人酒量超过陶渊明,像在邺水赞咏莲花,席上人的文采胜过谢灵运。良辰、美景、赏心、乐事这四种美好的事物都已经齐备,贤主、嘉宾千载难逢。向天空中远眺,在假日里尽享欢娱,天高地远,令人感到宇宙的无穷。欢乐逝去,悲哀袭来,我想到了事物的兴衰成败是有定数的。远望长安,东看吴会,陆地的尽头是深不可测的大海,北斗星多么遥远,天柱山高不可攀。关山重重难以跨越,有谁同情不得志的人?萍水相逢,大家都是异乡之客。心系朝廷,却不被召见,什么时候才能像贾谊那样去侍奉君王呢?

  唉!命运不顺,路途艰险。冯唐容易老,李广封侯难。把贾谊贬到长沙,并不是没有贤明的君主:梁鸿到海边隐居,难道不是在政治昌明的时代吗?不过是君子能够察觉事物的先兆,通达的人知道自己的命数罢了。年纪大了应当更有壮志,哪能在白发苍苍时改变自己的心志?处境艰难反该更加坚强,不能放弃凌云之志。这样即使喝了贪泉的水。仍然觉得心清无尘;处在干涸的车辙中,还能乐观开朗、北海虽然遥远,乘着旋风还是可以到达;过去的时光虽然已经消逝,珍惜将来的日子还不算晚。孟尝品行高洁,却空有报国之心;阮籍狂放不羁,怎能效仿他在无路可走时便恸哭而返?

  我,地位卑微,一个书生,虽然和终军的年龄相同却没有报国的机会;像班超那样有投笔从戎的豪情,也有宗悫“乘风破浪”的壮志。而今放弃一生的功名,到万里之外去侍奉父亲,不是谢玄那样的人才,却结识了诸位名家。过些天到父亲那里聆听教诲,一定像孔鲤那样有礼;今天有幸参加宴会,如登龙门。司马相如倘若没有杨得意的引荐,虽有文才也只能独自叹惋。既然遇到钟子期那样的知音,演奏高山流水的乐曲又有什么羞愧的呢?

  唉!名胜不能长存,盛宴难逢。兰亭集会的盛况已成陈迹,繁华的金谷园也变为废墟。有幸参加这次盛宴,故写小文以纪念;登高作赋,那就指望在座诸公了。竭尽心力,恭敬地写下这篇小序,我的一首四韵小诗也已写成请各位像潘岳、陆机那样,展现江海般的文才吧。

  巍然高大的滕王阁建在江渚之滨,当年滕王宴饮的场面已不再呈现。

  南浦轻云早晨掠过滕王阁的画栋,西山烟雨傍晚卷起滕王阁的珠帘。

  悠闲的云朵映在潭水上悠然渡过,变换的景物在星空下历数着春秋。

  修建这滕王阁的帝子在什么地方?只有槛外的长江水滚滚向东流淌。

创作背景

  关于《滕王阁序》写作时间,主要有四种说法:

  • “十三岁”说
      《太平广记》记载王勃“年十三省其父至江西”。《古今事文类聚前集》记载:“唐王勃字子安,六岁能文,词章盖世。年十三,侍父宦游江左,舟次马当,寓目山半古祠,危栏跨水,飞阁悬。”

  • “十四岁”说
      五代王定保记载:“王勃著《滕王阁序》,时年十四。都督阎公不之信。勃虽在座,而阎公意属子婿孟学士者为之,已宿构矣。及以笔纸巡让语宾客,物不辞。公大怒,拂衣而起,专令人其下笔。第一报云:‘南昌故郡,洪都新府。’公曰:‘是亦老生常谈。’又报云:‘星分翼轸,地接衡庐。’公闻之沉吟不言。又云:‘落霞与孤鹜齐飞,秋水共长天一色。’公矍然而起,曰:此真天才,当垂不朽矣!’遂请宴所,极欢而县。”
      

  • “二十二岁”说
      清初吴楚材等注《古文观止》认为作于“咸亨二年”(671年),王勃时年二十二岁。其注云:“咸亨二年,阎伯屿为洪州牧,重修。九月九日,宴宾僚于阁。欲夸其婿吴子章才,令宿构序。时王勃省父,次马当,去南昌七百里。梦水神告曰,助风一帆。达旦,遂抵南昌与宴,阎请众宾序,王勃不辞,阎恚甚,密令吏,得句即报。至落霞二句,叹曰,此天才也。想其当日对客挥毫,珍词绣句,层见叠出,海是奇才。”清人蒋清翊在《子安集注》中亦主张作于“省父”六合县之时。
      

  • “二十九岁”说
      元代辛文房《唐才子传》认为《滕王阁序》是王福峙谪交趾(今越南北部)之后。王勃前往省亲,过南昌而作。父福时坐是左迁交趾令。勃往省觐途过南昌,时都督阎公新修滕王阁成,九月九日,大会宾客,将令其婿作记,以夸盛事。勃至入谒,帅知其オ,因请为之。物欣然对客操觚,顷刻而就,文不加点,满座大惊。酒曲辞别,帅赠百,即举帆去,至炎方,舟入洋海溺死,时年二十九。”这里所说的“二十九”是虚岁。
      
      总之,这首《滕王阁序》是诗人为滕王阁而写的一首并序诗歌。

作品鉴赏

文学赏析

  《滕王阁序》全文行思缜密,紧扣题目,不拘一格,全文可分为四部分。
第一自然段为第一部分,写洪府地势雄伟、“物华天宝”“人杰地灵”“主人贤德”“高朋满座“。“豫章故郡,洪都新府”点明滕王阁所在地点,再详写其方位在翼、轸星宿的分野,从地理位置上看连接着湖南衡山和江西庐山,由上及下,再一笔荡开,写南昌地势:三江为襟,五湖为带,胸怀楚国而指引吴越。本为滕王阁作序,开篇却避开宴会和阁楼,不落俗套,气势高卓。“物华天宝”一句到“王将军之武库”一句,写南昌物产丰富,人才济济,称赞宴会宾主“尽东南之美”“高朋满座”“胜友如云”。最后一句,简述自己来到这里参加宴会的缘由。宴会盛况寥寥数笔带过,接下来是文章最重要的部分。

  第二、三自然段为第二部分。作者由近及远,从壮丽的楼阁到秀丽的山川,浓墨重彩地描写了滕王阁秋景,展开了一幅流光溢彩、错落有致、上下浑然天成、虚实相映成趣的滕王阁三秋图。“潦水尽而寒潭清,烟光凝而暮山紫。”这两句在静止中表现了光影色彩的变化,将湖光山色写得极富生命力。积水消尽后寒潭显出一片清澈,傍晚时分,淡淡的云烟凝聚着重重的暮霭,水天之间呈现出一片盈盈的紫光。这一句在色彩浓淡的变化中描绘秋意正浓的晚景,一个“寒”字写出秋高气爽, “寒潭”与“暮山”一近一远构成了错落的景致,这一句被誉为“写尽九月之景”。接下来是虚写,作者带着读者驾着马车在高高的山路上,在崇山峻岭里遍访秋日风景,来到昔日帝子居住的长洲,找到仙人休养过的宫殿。接着从众多名胜中将滕王阁烘托而出——“层峦耸翠,上出重霄;飞阁流丹,下临无地”。山峦重叠,山峰耸入云霄;凌空的飞檐丹辉欲流,仿佛直插大地。作者在一上一下之间仅仅用了十六个字就把楼阁高耸入云的气势写得蔚为壮观,把楼阁的独特风貌写得栩栩如生,这一句借着俯仰视角的改变,使上下浑然天成。“鹤汀凫渚,穷岛屿之萦回;桂殿兰宫,即冈峦之体势。”这两句写滕王阁周围的动物和植物,白鹤野鸭在萦回的小岛上畅游,洒满兰桂花香的宫殿掩映在起伏的山峦之中,使滕王阁犹如众星捧月一般,显出恢弘的气势。作者写到在滕王阁上登高远望极目之景:打开绣花的阁门来俯视雕梁画栋的屋脊,远阔的山川平原尽收眼底,近处的江河之水蜿蜒曲折令人惊奇。楼宇巷陌中尽是富贵人家;舸舰泊满渡口,都是装饰精美的雀舫龙舟。秀美山川、繁华市井、众多舟楫上承第一段的“物华天宝,人杰地灵”,又与下面的“渔舟唱晚” “雁阵惊寒”共同构成一幅情景交融、动静结合的图画。这一段中属“落霞与孤鹜齐飞,秋水共长天一色”一句最为人称道。这句话是一个视觉的飨宴,整幅画面的主体是红色的夕阳余晖和蓝绿色的水光接天的模样,白色的野鹭穿插其间。色彩美,动态美,虚实美,空间立体美,带给读者无暇的想象。
  
  第四、五自然段为第三部分,写众人宴会上登临逸兴,进而兴尽悲来,怀古议论,引出对人生际遇的感慨。作者以起伏跌宕的笔势,从“逸兴遄飞”写到了“兴尽悲来”。第四段头两句“遥襟甫畅,逸兴遄飞。爽籁发而清风生,纤歌凝而白云遏”,写的是宴会时丝竹管弦、轻歌曼舞的欢乐场景。接着将在座宾客杯中豪情和笔下才华堪比陶渊明、谢灵运。良辰美景与共,赏心乐事具备,宾主难得相聚,极目远望,尽情地欢娱。到这里写的都是登临逸兴的乐。下面一句“天高地迥,觉宇宙之无穷;兴尽悲来,识盈虚之有数”。从宇宙无穷想到兴衰有尽:回望长安犹在夕阳下,吴会却如在云海间。大地有穷尽,而南海深不可测,擎天之柱不可攀,北斗星辰遥远:关山难越,谁来为失意人悲痛?萍水相逢,都是异乡漂泊之人。满怀抱负,王宫何时能见?皇帝的召见,又要等到何年?作者以“失路之人”自指,叹息自己的命运。作者虽满腔热血,才华横溢却因恃才傲物、放荡不羁而被当时社会所不容。壮志难酬,所以在这里作者由宇宙的无限而想到人生有限、短暂,表露出对时光流逝却功业难成的感慨;他悲叹盈虚有数,透出无法扭转命运的无奈,为自己只能流落南海之滨,无力跻身帝都长安为国效力而感到悲伤。在第五段中,作者用典故把自己比做贾谊、梁鸿、冯唐、李广,来描述自己现在遭遇的困境,但作者没有在悲伤中停留太久,转而用自己的乐观精神给这一段咏叹做了更好的注解。作者表示自己仍是达人知命, “老当益壮,宁移白首之心;穷且益坚,不坠青云之志。”身处逆境仍旧心胸开朗,立志报国。这一段所用典故较多,但却合理恰当毫无堆砌之感,王勃写自己怀才不遇、深陷困境的矛盾心理,却又用一种处世的乐观精神加以化解,这种高尚的情怀,千百年来引起了众多文人雅士的共鸣。
  
  第六、七段为第四部分,简述自己的旅程和志向,对宾主的知遇表示感谢,对参加宴会并饯别作序表示荣幸,这一段内容与开头遥相呼应,再一次紧扣主题。
在艺术上,《滕王阁序》有以下写作特色:

  (1)句式错落,节奏分明
  
  全文以四六句为主,杂以六四句。七字句,六字句,四字句,三字句,二字句,乃至一字句,这些句式,根据表意的需要而交错运用,使节奏分明,内容起承转合。一般来说,二字句用于抒情(文中有两处:“嗟乎”“呜呼”)。三字句、四字句用于一个话题的开始或转折。六字句或七字句连用,为平实的叙述。四六句或六四句连用,为叙述或抒情的展开部分。仅有一个一字句“勃”,是自指兼表提顿。这样,全篇的行文,既起伏跌宕,又自然流转。
  
  (2)骈俪藻饰,辞采华美
  
  全篇采用对偶句,不但字面相对,而且音韵大体相对。如“天高地迥,觉宇宙之无穷;兴尽悲来,识盈虚之有数。”“屈贾谊于长沙,非无圣主;窜梁鸿于海曲,岂乏明时?”“落霞与孤鹜齐飞,秋水共长天一色”等,一句中平仄交替,上下句之间又平仄相对。如此讲求音律,又不影响意义表达,写出来的句子抑扬顿挫,富于乐感,富于诗意。这篇序文,如“物华天宝”“俊采星驰”“紫电青霜”“钟鸣鼎食”“青雀黄龙”“睢园绿竹”“邺水朱华”等,都是讲求辞采的典型例子。这样,文章辞采华美,赏心悦目。
  
(3)运用典故,简练含蓄

  这篇序文用了大量典故来叙事抒情,有的是历史故事,有的是前人文句,而运用的手法又有所不同,有的是明用,如“冯唐易老,李广难封”;有的是暗用,如“酌贪泉而觉爽,处涸辙以犹欢”;有的是正用,如“孟尝高洁,空余报国之情”;有的是反用,如“阮籍猖狂,岂效穷途之哭”。典故的运用,加强了文章的表达效果。

名家点评

  • 唐代
      韩愈《新修滕王阁记》:愈少时则闻江南多临观之关,而滕王阁独为第一,有瑰伟绝特之称。及得三王所为序、赋、记等,壮其文辞,益欲往一观而读之,以忘吾忧。
      
  • 宋代
      洪迈《容斋续笔》:唐人诗文,或于一句中自成对偶,谓之当句对。盖起于《楚辞》“蕙叠、兰藉”,“桂酒、椒浆”,“斫冰、积雪”。自齐、梁以来,江文通、庾子山亦如此。如王勃《宴滕王阁序》一篇皆然。谓若:“襟三江、带五湖”,“控蛮荆、引瓯越”,“龙光、牛斗”,“徐孺、陈蕃”,“腾蛟起凤、紫电青霜”,“鹤汀凫渚、桂殿兰宫”,“钟鸣鼎食之家、青雀黄龙之舳”,“落霞、孤鹜”,“秋水、长天”,“天高地迥、兴尽悲来”,“宇宙、盈虚”,“丘墟、已矣”之辞是也。
      
  • 明代
      胡应麟《诗薮》:神俊无前,六代体裁,几于一变。即“画栋”“珠帘”四韵,亦唐人短歌之绝。
      
  • 清代
      唐德宜《古文翼》卷八引曹德培语:此序一起极有力量,而于洪波汹涌中,随结随却,尤为超特。前半曲描婉写,璧缀珠联,奇丽极矣。后半独能别开生路,以悠扬怀抱,写出磊落事情,抚今思古,吊往追来。盖前半以景胜,后半以情胜。非情无以显景,非景无以寓情。而前半写景,景中有情;后半写情。情中有景。
      
      林云铭《古文析义》:余细读之,见起初以南昌名胜,从天引起地,从地引起人,又从人分出宾主。此起手铺叙之伦也。因就宾主句落下间公,兼点字文,并许多佳客与己为会之时,及所会之地。此入题铺叙之伦也。到阁之后,先写阁居山水之间,增山水之胜,开阁而眺。再写阁外所见之实景,及当秋之奇景。此形容铺叙之伦也。逸兴既发,或闻风声,或聆歌声,或德星饮酒,或见文土临池。凡游宴中所当有而不能备有者,皆无不有,诚可为乐。此序事铺叙之伦也。游乐已极,由壮生悲,人情皆然,穷旅尤甚。以为在会诸客中,必有不能忘情于不遇,与己相等者。此感慨铺叙之伦也。末以时命自安,藏器待时之意,为在会不得志诸君子慰藉。再自叙同此沦落,而壮志不衰。今因省父途中,得遇佳会,虽平日之词章,见诎于君上,而得伸于知己,亦为可幸。此收东铺叙之伦也。复把盛衰不常之理,以感慨发作余波,并系以诗,寓吊古之意,此结尾铺叙之伦也。其中布置之巧,步步衔接,步步脱却,皆有开合相因之妙。
      
      王夫之《姜斋诗话》卷三:滕王阁连甍市廛,名不称实;徒以王勃一序,脍炙今古。求所谓“飞阁流丹、飞云卷雨”者,何有也?吴下管元心(正传),令永新,作一绝书版悬阁上,末句云:“争传画栋珠帘句,江上藏风笑杀人。”
      
      李扶九原编、黄仁黼重订《古文笔法百篇》卷十八:自来手八叉、才七步如温庭筠、曹子建辈,类皆不免枚皋速而不工之弊。至求其可以三《二京》而四《三都》者,则又非相如之工而不速不可。古今所传,惟祢正平《鹦鹉》一篇,庶几兼之。然年非弱冠,而又有黄祖娱宾之迫,不得不顺从以远害,尽辞以效愚。若夫子安路出洪州,躬逢胜饯,既无避祸之苦,又叨末座之宾,出纸慨然,此阎公之所以见恚也。而序珠来玉举笔有神,初不让八叉七步之捷,竟致陈思铜雀能倾魏武之心,以视孟坚之折西宾,太冲之访岷事。其工拙又如何也?然非遗墨一梦,安见十三楮子不减洛神,能令阎公叹为天才而矍然起敬哉!
      
  • 现代
      古典文学专家袁行霈《中国文学史》:唐代骈文也出现了一些新的变化,自初唐四杰始,不少作品已于工整的对偶、华丽的辞藻之外,展示出流走活泼的生气和注重骨力的刚健风格,如王勃的《滕王阁序》。
      

后世影响

一、地位
  从内容上看,《滕王阁序》拓展了骈文的艺术境界。在艺术形式上,《滕王阁序》接受了六朝抒情小赋的传统,又在骈文的形式上加以散文化,达到了内容美与形式美的统一。《滕王阁序》既是六朝骈文之新变,也是唐朝骈文通俗化格律化之先声。
  
二、成语
  人杰地灵:来源于“物华天宝,龙光射牛斗之墟;人杰地灵,徐孺下陈蕃之榻。”
萍水相逢:来源于“关山难越,谁悲失路之人?萍水相逢,尽是他乡之客。”

三、教材收录
  《滕王阁序》被入选高中语文必修五人教版教材中。
  

作者简介

  王勃(650—676年),字子安,绛州龙门(今山西河津)人。隋末学者文中子王通之孙,唐代诗人。年十四,举幽素科,授朝散郎。因作文得罪唐高宗而被放逐,漫游于蜀中。后补虢州参军,犯死罪,遇赦,革职。年二十七,因渡南海探望父亲,溺水受惊而死。工诗能文,与杨炯、卢照邻、骆宾王齐名,并称“初唐四杰”。王勃在诗歌体裁上擅长五律和五绝,代表作品有《送杜少府之任蜀州》等;主要文学成就是骈文,代表作品有《滕王阁序》等。

《醉蓬莱·见扬州独有》

见扬州独有,天下无双,号为琼树。
占断天风,岁花开两次。
九朵一苞,攒成环玉,心似珠玑缀。
瓣瓣玲珑,枝枝洁净,世上无花类。
冷露朝凝,香风远送,信是琼瑶贵。
料得天宫有,此地久难留住。
翰苑才人,贵家公子,都要看花去。
莫吝金钱,好寻诗伴,日日花前醉。

作者简介

秦观(1049-1100),扬州高邮人,字少游,又字太虚,号淮海居士。少从苏轼游。神宗元丰八年进士。有《淮海集》

Windows 平台使用自带工具进行端口转发

原文:Windows 平台使用自带工具进行端口转发

一、前言

   系统:Windows 10 或 Windows Server

二、应用场景

    在不能直接访问计算机某些端口的时候,我们可以使用 Windows 系统自带的端口转发工具转发到能够直接访问的计算机端口,以便进行网络访问。

三、操作步骤

   注意:以下操作需要在【以管理员身份运行】【命令提示符】进行。

   1、建立端口转发规则:192.168.1.100:33890 <=> 192.168.1.101:3389

   在 192.168.1.100 上执行:
netsh interface portproxy add v4tov4 listenaddress=192.168.1.100 listenport=33890 connectaddress=192.168.1.101 connectport=3389
# listenaddress 监听地址,如果本机有多个地址,且需要监听所有地址,此参数可以省略。
# listenport    监听端口,用于监听网络请求的端口。
# connectaddress连接地址,用于转发网络请求的地址。
# connectport   连接端口,用于转发网络请求的端口。
# 可以简写为:
netsh interface portproxy add v4tov4 listenport=33890 connectaddress=192.168.1.101 connectport=3389

执行完毕后,我们可以通过访问 192.168.1.100:33890 来访问 192.168.1.101:3389 了。如果192.168.1.100 开启了防火墙,需要在防火墙放行 33890 端口。

   2、显示端口转发规则:

   在192.168.1.100 上执行:
# 显示所有转发规则
netsh interface portproxy show all
 
# 仅显示 IPv4ToIPv4 的转发规则
netsh interface portproxy show v4tov4
 
# 仅显示 IPv6ToIPv6 的转发规则
netsh interface portproxy show v6tov6
 
# 仅显示 IPv4ToIPv6 的转发规则
netsh interface portproxy show v4tov6
 
# 仅显示 IPv6ToIPv4 的转发规则
netsh interface portproxy show v6tov4

3、删除端口转发规则

       在192.168.1.100 上执行

# 如果在创建端口转发规则的时候有 listenaddress ,在删除的时候需要加上 listenaddress
netsh interface portproxy delete v4tov4 listenaddress=192.168.1.100 listenport=33890
 
# 如果在创建端口转发规则的时候没有 listenaddress ,在删除的时候不用加 listenaddress
netsh interface portproxy delete v4tov4 listenport=33890

lftp命令 非常详细的lftp指令

lftp命令_非常详细的lftp指令_weixin_39828457的博客-CSDN博客

lftp的意思是用lftp登录到ftp服务器上

lftp ip -p port -u user,’password’ -e’commands ; bye’

下面介绍下ftp里面常用的指令

1、登录ftp

代码:lftp 用户名:密码@ftp地址:传送端口(默认21)

用法

(1)lftp username:password@127.0.0.1:21 回车

(2)lftp username@127.0.0.1 回车 ##默认21端口 回车后输入密码

(3)lftp 127.0.0.1 回车 ##回车后 login 登录

(4)lftp 回车 –> open 127.0.0.1 –> login 登录


2、lftp中文乱码问题

如果登录后看到的都是中文乱码(因为一般本地都是utf-8的编码),怎么半呢?可以用 set 命令来解决:

set ftp:charset gbk(或者 gb2312 或 utf-8) ##设置ftp端的编码格式

set file:charset utf-8 (…同上) ##设置本地编码格式

附:set命令的技巧

(1)输入set 查看已经设置好的命令

(2)set -a 查看所有可以设置的命令


3、查找ftp端文件

ls *.txt ##查找当前目录下的所有txt文件

ls ./123/ ##列出123目录下所有文件

find . -name “*.txt” ##递归查找站点上所有的txt文件

find ./xx -name “*.txt” ##查找xx目录下所有的txt文件

附1:

ls第二次读取的是本地缓存,可以用 rels 代替 ls

或者catch off / catch on 来开关catch,catch flush清空本地catch

附2: 浏览本地目录的命令可用!ls, 如 !ls /usr/local/bin/

4、下载文件下载文件之前要先设置好本地的目录,用来存放下载的文件

lcd /home/123/web ##设置本地存放目录 默认为 /home/usr

get 123.txt ##下载123.txt文件到 /home/123/web 中

get -c 123.txt ##断点续传下载

mget *.txt ##批量下载所有txt文件

mget -c *.txt ##断点续传

mget -c ./123/aaa/*.txt ##断点续传、批量下载ftp端aaa目录下的所有txt文件

pget -c -n 10 file.dat

##以最多10个线程以允许断点续传的方式下载file.dat

##可以通过设置 set pget:default-n 5 的值而使用默认值。

mirror aaa/

##将aaa目录整个的下载下来,子目录也会自动复制 本地自动建立目录

5、上传文件put 123.txt ##同下载

mput *.txt ##同下载

mirror -R aaa/ ##同下载

6、设置被动/非被动模式set ftp:passive-mode 1 ## 1 被动 0非主动

多任务处理ctrl+z ##将当前进行的任务移交后台处理

wait ##将后台处理任务调至前台查看

jobs ##查看后台进行的任务列表

kill all 或者 job_no ##删除所有任务 或 指定的任务

##将任务加入任务列表

queue get 123.txt

queue put 234.txt

queue mirror aaa/

queue ##查看任务列表j

obs ##查看后台任务列表

queue start ##开始任务列表

queue stop ##停止任务列表


7、其他命令

定义别名:alias []

alias less more

alias reconnect “close; cd .”

直接输入 alias 即可看到目前定义了那些别名。如果只输入 alias name 的话, 则是取消 name 这个别名。

bookmark SUBCMD

设定书签, 可将目前站台及所在目录设成书签, 下次可直接进来, 不用再 cd 来 cd 去的

bookmark add name 用来新增名称为 name 的书签

bookmark del name 删除名称为 name 的书签

bookmark list 显示目前有设定那些书签(另外直接打 bookmark 和 bookmark list 的结果一样)

bookmark edit 呼叫编辑器修改书签 (~/.lftp/bookmarks)

cd 切换远端目录

cache SUBCMD

管理 lftp 的 cache

rels []

从 cache 中显示远端档案列表

rels 则不会从 cache 中读取

recls opts [path/]pattern

从 cache 中显示远端的档案列表, 应该算是 ls 的加强版, 有很多参数可用,应该是可用来产生各种不同>的档案列表以供其他程式使用。

recls 则不会从 cache 中读取

du options

计算远端整个目录占用容量

get OPTS -o

抓取远端档案

get rfile -o lfile

抓 rfile 到本地改名为 lfile

-c 为续传

-E 抓档完成后, 将远端的档案砍了

-a 为 ascii mode, 预设为 binary mode

-O 设定 base directory 为本地端放档案的目录

mget OPTS

下载远端档案(可用 wildcard expansion 也就是 *)

pget OPTS -o

使用多个连结来下载档案, 预设为五个。

-n 3 为叁个连结

jobs -v

显示目前有那些程序在背景执行

-v 显示详细的资讯(-v 可多加几个来显示更详细的资讯)

lcd

切换本地端的目录

mirror OPTS remote [local]

下载整个目录(楼上的 get 只能用来抓档案)

-c 续传

-e 这个要小心一些, 比较远端和本地端的档案, 假如远端没有的, 就将本地端的档案删除, 也就是将本地端和远端资料同步。

-R 上传整个目录

-n 只下载较新的档案

-r 不用递回到目录中

–parallel=n 同时下载 n 个档案(预设一次只下载一个)

Git Flow 的正确使用姿势

Git Flow 的概念

  在使用Git的过程中如果没有清晰流程和规划,否则,每个人都提交一堆杂乱无章的commit,项目很快就会变得难以协调和维护。 Git版本管理同样需要一个清晰的流程和规范。 Vincent Driessen 为了解决这个问题提出了 A Successful Git Branching Model 以下是基于Vincent Driessen提出的Git Flow 流程图

Git Flow 的常用分支

  • Production 分支

也就是我们经常使用的Master分支,这个分支最近发布到生产环境的代码,最近发布的Release, 这个分支只能从其他分支合并,不能在这个分支直接修改

  • Develop 分支

这个分支是我们是我们的主开发分支,包含所有要发布到下一个Release的代码,这个主要合并与其他分支,比如Feature分支

  • Feature 分支

这个分支主要是用来开发一个新的功能,一旦开发完成,我们合并回Develop分支进入下一个Release

  • Release分支

当你需要一个发布一个新Release的时候,我们基于Develop分支创建一个Release分支,完成Release后,我们合并到Master和Develop分支

  • Hotfix分支

当我们在Production发现新的Bug时候,我们需要创建一个Hotfix, 完成Hotfix后,我们合并回Master和Develop分支,所以Hotfix的改动会进入下一个Release

Git Flow 如何使用

  • Master/Devlop 分支

所有在Master分支上的Commit应该打上Tag,一般情况下Master不存在Commit,Devlop分支基于Master分支创建

  • Feature 分支

Feature分支做完后,必须合并回Develop分支, 合并完分支后一般会删点这个Feature分支,毕竟保留下来意义也不大。

  • Release 分支

Release分支基于Develop分支创建,打完Release分支之后,我们可以在这个Release分支上测试,修改Bug等。同时,其它开发人员可以基于Develop分支新建Feature (记住:一旦打了Release分支之后不要从Develop分支上合并新的改动到Release分支)发布Release分支时,合并Release到Master和Develop, 同时在Master分支上打个Tag记住Release版本号,然后可以删除Release分支了。

  • Hotfix 分支

hotfix分支基于Master分支创建,开发完后需要合并回Master和Develop分支,同时在Master上打一个tag。

Git Flow 命令示例

创建 Devlop

git branch develop
git push -u origin develop

开始 Feature

# 通过develop新建feaeure分支
git checkout -b feature develop
# 或者, 推送至远程服务器:
git push -u origin feature

# 修改md文件
git status
git add .
git commit    

完成 Feature

git pull origin
develop git checkout develop

#--no-ff:不使用fast-forward方式合并,保留分支的commit历史
#--squash:使用squash方式合并,把多次分支commit历史压缩为一次

git merge --no-ff feature
git push origin develop

git branch -d some-feature

# 如果需要删除远程feature分支: 
git push origin --delete feature  

开始 Release

git checkout -b release-0.1.0 develop

完成 Release

git checkout master
git merge --no-ff release-0.1.0
git push

git checkout develop
git merge --no-ff release-0.1.0
git push

git branch -d release-0.1.0
git push origin --delete release-0.1.0 
  
# 合并master/devlop分支之后,打上tag
git tag -a v0.1.0 master
git push --tags

开始 Hotfix

git checkout -b hotfix-0.1.1 master 

完成 Hotfix

git checkout master
git merge --no-ff hotfix-0.1.1
git push

git checkout develop
git merge --no-ff hotfix-0.1.1
git push

git branch -d hotfix-0.1.1
git push origin --delete hotfix-0.1.1

git tag -a v0.1.1 master
git push --tags

使用建议

如果你的代码没有清晰流程和规划,那么强烈推荐使用Vincent Driessen 提出的GIt flow 让你的代码管理骚起来。

结尾

本站文章图片等等来源于网络,仅作为学习之用,版权归原作者所有.如果侵犯了您的权益,请来信告知,我会尽快删除.


作者:qingwenLi
链接:https://www.jianshu.com/p/41910dc6ef29

Opencv-Python 图像透视变换cv2.warpPerspective

# -*- coding:utf-8 -*-
import cv2
import numpy as np
import sys
 
img = cv2.imread("test.jpg")
#cv2.namedWindow('original',2)
#cv2.imshow("original", img)
 
# 可选,扩展图像,保证内容不超出可视范围
img = cv2.copyMakeBorder(img, 200, 200, 200, 200, cv2.BORDER_CONSTANT, 0)
w, h = img.shape[0:2]
 
anglex = 0
angley = 30
anglez = 0  # 是旋转
fov = 42
r = 0
 
def rad(x):
    return x * np.pi / 180
 
def get_warpR():
    global anglex,angley,anglez,fov,w,h,r
    # 镜头与图像间的距离,21为半可视角,算z的距离是为了保证在此可视角度下恰好显示整幅图像
    z = np.sqrt(w ** 2 + h ** 2) / 2 / np.tan(rad(fov / 2))
    # 齐次变换矩阵
    rx = np.array([[1, 0, 0, 0],
                   [0, np.cos(rad(anglex)), -np.sin(rad(anglex)), 0],
                   [0, -np.sin(rad(anglex)), np.cos(rad(anglex)), 0, ],
                   [0, 0, 0, 1]], np.float32)
 
    ry = np.array([[np.cos(rad(angley)), 0, np.sin(rad(angley)), 0],
                   [0, 1, 0, 0],
                   [-np.sin(rad(angley)), 0, np.cos(rad(angley)), 0, ],
                   [0, 0, 0, 1]], np.float32)
 
    rz = np.array([[np.cos(rad(anglez)), np.sin(rad(anglez)), 0, 0],
                   [-np.sin(rad(anglez)), np.cos(rad(anglez)), 0, 0],
                   [0, 0, 1, 0],
                   [0, 0, 0, 1]], np.float32)
 
    r = rx.dot(ry).dot(rz)
 
    # 四对点的生成
    pcenter = np.array([h / 2, w / 2, 0, 0], np.float32)
 
    p1 = np.array([0, 0, 0, 0], np.float32) - pcenter
    p2 = np.array([w, 0, 0, 0], np.float32) - pcenter
    p3 = np.array([0, h, 0, 0], np.float32) - pcenter
    p4 = np.array([w, h, 0, 0], np.float32) - pcenter
 
    dst1 = r.dot(p1)
    dst2 = r.dot(p2)
    dst3 = r.dot(p3)
    dst4 = r.dot(p4)
 
    list_dst = [dst1, dst2, dst3, dst4]
 
    org = np.array([[0, 0],
                    [w, 0],
                    [0, h],
                    [w, h]], np.float32)
 
    dst = np.zeros((4, 2), np.float32)
 
    # 投影至成像平面
    for i in range(4):
        dst[i, 0] = list_dst[i][0] * z / (z - list_dst[i][2]) + pcenter[0]
        dst[i, 1] = list_dst[i][1] * z / (z - list_dst[i][2]) + pcenter[1]
 
    warpR = cv2.getPerspectiveTransform(org, dst)
    return warpR
 
def control():
    global anglex,angley,anglez,fov,r
 
    # 键盘控制
    if 27 == c:  # Esc quit
        sys.exit()
    if c == ord('w'):
        anglex += 1
    if c == ord('s'):
        anglex -= 1
    if c == ord('a'):
        angley += 1
        print(angley)
        # dx=0
    if c == ord('d'):
        angley -= 1
    if c == ord('u'):
        anglez += 1
    if c == ord('p'):
        anglez -= 1
    if c == ord('t'):
        fov += 1
    if c == ord('r'):
        fov -= 1
    if c == ord(' '):
        anglex = angley = anglez = 0
    if c == ord('e'):
        print("======================================")
        print('Rotation Matrix:')
        print(r)
        print('angle alpha(anglex):')
        print(anglex)
        print('angle beta(angley):')
        print(angley)
        print('dz(anglez):')
        print(anglez)
 
 
while True:
 
    warpR = get_warpR()
 
    result = cv2.warpPerspective(img, warpR, (h, w))
    cv2.namedWindow('result',2)
    cv2.imshow("result", result)
    c = cv2.waitKey(30)
    control()
 
cv2.destroyAllWindows()

运行效果:

控制:

  • s控制垂直方向上的形变
  • a和d控制水平方向上的行变
  • u和p控制角度旋转
  • e 输出当前旋转矩阵参数

原文: https://blog.csdn.net/dcrmg/article/details/80273818

How rdp passwords are encrypted

Ever wondered how mstsc saves passwords? If you open an RDP file with a text editor like Notepad you can see the encrypted password. In this article I will show you how to encrypt and decrypt these passwords. Besides password recovery this enables you to create rpd files programmatically or perhaps update the password in many rdp files with a batch file.

So if we save a password with mstsc what does it look like? To see that open an rdp file with a text editor (eg Notepad) and you will see something like this:

screen mode id:i:1 
desktopwidth:i:1280 
desktopheight:i:750 
session bpp:i:24 
winposstr:s:2,3,188,8,1062,721 
full address:s:MyServer 
compression:i:1 
keyboardhook:i:2 
audiomode:i:0 
redirectdrives:i:0 
redirectprinters:i:0 
redirectcomports:i:0 
redirectsmartcards:i:0 
displayconnectionbar:i:1 
autoreconnection enabled:i:1 
username:s:MyUserName 
domain:s:MyDomain 
alternate shell:s: 
shell working directory:s: 
password 51:b:01000000D08C9DDF0115D1118C7A00C04FC297EB0100000052A9E191EA75A948B359790578C9371A0000000008000000700073007700000003660000A8000000100000000A1DCCD2E50775CA25EC3857164B34DC0000000004800000A000000010000000FCE1A645B9B61AA450946BB6F955058108020000D83591CA47562D6DDAA689F050AE145039EBE22E00D1D3AEAA98373C7B63C3E8E7149072DF989EA43EFCE20513AD3D27B11BE7F17066A688E1DCE828AF85460AAC327B38E90776DB962888E4393D19637578984B19A187AAD95F6D2726ADE7DD315FF56C15FF5B3031014EDDCC3C24D1B81779AFDB006EE575F5BEFB8D2D2138D9D9D642BBB251CC5ED7226968764856EC660A646BACE748A13D6002A9A537AA70710615650B9387EED66DE28BD57B304BBDD7B581B943DA628EB0289E30A8BA784B76F7885BECCAB4FEF7820E97EE3C6E036EEAF6EAA669288DF2FCACC9BEC045C907EBBDE87AFB8CC6B07A600BD63AC891B61D95C2265DD9FD5E635D61BFBF5EDC28311375066611C610FB533D64515B643C82F57D9B183B05C156D91BC0974D38E546022B139E82452E6F1EDF76E52F732C3904E5E433F8F3D488DB0698427DBB0791A9F207F8CB6654CB8410BAF4A59C4F9E821E589ABC1E6E6E1D432181B690408F6884FE1007895A4D26D4A5A2C7458EE747DA35D44AC9FB08AB5477EA3E7CCDB3E37EE20FAFD0D0CF9584E420598B7003B347943AC28048F45E0FD21AD08148FFADCE0E7877219259A7BE722FFAE845A429BA2CF0A71F2D19EA7495530FABDB5106E8D404A38A7E6394C38457640EA7398C5D55F0C4D342CC6A39C77E10A2A5145AEA40B14F5C7C3760334D83C9BE748383FADE231248537353817D51F7B44F61B406ABC61400000071C354139F458B02D978015F785B97F7F6B307380 
disable wallpaper:i:1 
disable full window drag:i:1 
disable menu anims:i:1 
disable themes:i:0 
disable cursor setting:i:0 
bitmapcachepersistenable:i:1

As you can see the password is somehow encrypted before it was saved and automatically decrypted when you open the file with mstsc. .

I did some analysis on mstsc.exe and mstsc uses the functions CryptProtectData and CryptUnProtectData which are both exported by crypt32.dll. Since those API calls are documented let’s try to encrypt a password with mstsc and one ourselves and compare the output:

function CryptRDPPassword(sPassword: string): string; 
var DataIn: DATA_BLOB; 
    DataOut: DATA_BLOB; 
    pwDescription: PWideChar; 
    PwdHash: string; 
begin 
  PwdHash := '';                                      

  DataOut.cbData := 0; 
  DataOut.pbData := nil;                                      

  // RDP uses UniCode 
  DataIn.pbData := Pointer(WideString(sPassword)); 
  DataIn.cbData := Length(sPassword) * SizeOf(WChar);                                      

  // RDP always sets description to psw 
  pwDescription := WideString('psw');                                      

  if CryptProtectData(@DataIn, 
                      pwDescription, 
                      nil, 
                      nil, 
                      nil, 
                      CRYPTPROTECT_UI_FORBIDDEN,  // Never show interface 
                      @DataOut) then 
  begin 
    PwdHash := BlobDataToHexStr(DataOut.pbData, DataOut.cbData); 
  end; 
  Result := PwdHash;                                      

  // Cleanup 
  LocalFree(Cardinal(DataOut.pbData)); 
  LocalFree(Cardinal(DataIn.pbData));                                      

end;

So we encrypt the password “secret” and compare this with the same password saved by mstsc
MSTSC:

01000000D08C9DDF0115D1118C7A00C04FC297EB0100000052A9E191EA75A948B359790578C9371A0000000008000000700073007700000003660000A8000000100000000A1DCCD2E50775CA25EC3857164B34DC0000000004800000A000000010000000FCE1A645B9B61AA450946BB6F955058108020000D83591CA47562D6DDAA689F050AE145039EBE22E00D1D3AEAA98373C7B63C3E8E7149072DF989EA43EFCE20513AD3D27B11BE7F17066A688E1DCE828AF85460AAC327B38E90776DB962888E4393D19637578984B19A187AAD95F6D2726ADE7DD315FF56C15FF5B3031014EDDCC3C24D1B81779AFDB006EE575F5BEFB8D2D2138D9D9D642BBB251CC5ED7226968764856EC660A646BACE748A13D6002A9A537AA70710615650B9387EED66DE28BD57B304BBDD7B581B943DA628EB0289E30A8BA784B76F7885BECCAB4FEF7820E97EE3C6E036EEAF6EAA669288DF2FCACC9BEC045C907EBBDE87AFB8CC6B07A600BD63AC891B61D95C2265DD9FD5E635D61BFBF5EDC28311375066611C610FB533D64515B643C82F57D9B183B05C156D91BC0974D38E546022B139E82452E6F1EDF76E52F732C3904E5E433F8F3D488DB0698427DBB0791A9F207F8CB6654CB8410BAF4A59C4F9E821E589ABC1E6E6E1D432181B690408F6884FE1007895A4D26D4A5A2C7458EE747DA35D44AC9FB08AB5477EA3E7CCDB3E37EE20FAFD0D0CF9584E420598B7003B347943AC28048F45E0FD21AD08148FFADCE0E7877219259A7BE722FFAE845A429BA2CF0A71F2D19EA7495530FABDB5106E8D404A38A7E6394C38457640EA7398C5D55F0C4D342CC6A39C77E10A2A5145AEA40B14F5C7C3760334D83C9BE748383FADE231248537353817D51F7B44F61B406ABC61400000071C354139F458B02D978015F785B97F7F6B307380

CryptRDPPassword:

01000000D08C9DDF0115D1118C7A00C04FC297EB0100000052A9E191EA75A948B359790578C9371A0000000008000000700073007700000003660000A800000010000000F68F88DF66E436846C077BF402E46EB90000000004800000A000000010000000FE8CEBCF943F9CEC9F3C3A1E0710BEC510000000A647D6ADB728E51F071C854F0BFFF66F140000003B271D41D3D256BCCC4DD255701C14B7489A081D

As you can see the length of a password encrypted by mstsc is 1329 bytes and the one from CryptRDPPassword is smaller. Actually mstsc generates fixed length passwords and our function’s length is based upon the password. Even more strange is that mstsc password is always 1329 bytes because the input password is unicode which should produce an even size length. It doesn’t really matter though because mstsc.exe accepts the smaller sized passwords without any problems.
For now I will leave with a demo tool I wrote to encrypt and decrypt rdp passwords. But in a followup article I will show you how te encrypt the passwords to the full length 1329 bytes the same way mstsc does.

Remote Desktop Password Encryption & Decryption Tool
Do you find this article usefull, why not leave a comment?

原文:https://www.remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted

DataTables列表移动端适配定义隐藏列

Responsive.breakpoints = [
    { name: 'desktop',  width: Infinity },
    { name: 'tablet-l', width: 1024 },
    { name: 'tablet-p', width: 768 },
    { name: 'mobile-l', width: 480 },
    { name: 'mobile-p', width: 320 }
];

分别表示在什么屏幕下显示该列。
比如desktop表示在PC版大屏幕时才显示该列,否则隐藏。
tablet-l表示1024的大小才显示该列,否则隐藏。
以此类推。

所以修改的代码只需要修改列头th的class名即可,如下:

<thead>
    <tr>
        <th width="8%" class="mobile-l">姓名</th>
        <th width="10%" class="mobile-l">电话</th>
        <th width="10%" class="mobile-l">性别</th>
        <th width="10%" class="desktop">时间</th>
        <th width="8%" class="desktop">操作</th> 
    </tr>
</thead>