字符混淆器

3

我在想是否有一种方法(使用ASP.NET C#)可以“洗牌”字符串的内容,但仍然能够单击另一个按钮并将其“解除洗牌”回到原始内容,而不保存原始内容?

谢谢 :)

示例:

"This is not shuffled."

"isuo .tffsnl iTh shed"

...And then I click the "UNShuffle" button and it becomes normal again:

"This is not shuffled."

1
@j-t-s,public int Random() { return 4; },不,您不能随机洗牌并在不保存任何元数据的情况下将其返回到原始状态。但是,如果您确切地知道字符是如何移动的,那么您可以将它们移回去。 - Filip Ekberg
2个回答

8
易如反掌: suffling
var rnd = new Random();
string unsuffled = "This is not shuffled.";
string shuffled = new string(unsuffled.OrderBy(r => rnd.Next()).ToArray());

但由于它是随机的,除非您存储先前的字符串或映射,否则无法取消混淆。

所以,如果我存储Random();然后在去除洗牌时只使用存储的随机引用,那应该可以了,对吧?【谢谢】 - anon271334
2
不行,你必须存储用于生成随机数的种子(并使用它创建新实例),或者存储从随机实例中获取的随机值。即使这样,我也想不出你如何知道原始顺序。 - Matt Mitchell

6

好的,您需要保存一些东西。一个简单的想法:

  • 使用随机数生成器生成一个随机种子。
  • 创建一个新的Random实例来使用该种子进行洗牌
  • 使用修改后的Fisher-Yates shuffle进行洗牌
  • 保留种子

然后这个洗牌是可逆的——尽管需要付出一点努力。(我可能会用相同的方式对数字0...(n-1)进行洗牌,然后反向映射字符。)

棘手的部分是,您确实需要种子——这有点像存储密码哈希值的盐。您必须有一些额外的信息来说明它是如何被洗牌的,否则您将不知道“abc”是来自“bac”还是“cab”,例如。


1
如果洗牌只需要看起来随机,那么您可以从洗牌后的文本计算出一个种子,而无需存储种子。使用类似于(未)洗牌字符串的各个字符的ASCII值之和的东西应该就可以了。 - Cornelius
1
@j-t-s: 所以你觉得同样的输入总是被“洗牌”到同样的输出没问题吗? - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接